Сравнение KOL-MCK и VCL (Сomparison KOL-MCK and VCL) Delphi

  1. Всем привет!
    Наконец-то пришло время для этой статьи. Она долго вынашивалась в моей голове, и все такое..., поэтому...

    Это будет не простая статья о возможностях KOL & MCK. Это будет статья-сравнение функционала KOLMCK и стандартного набора VCL-библиотек Delphi. Так читателю, по мнению автора, будет проще переходить с VCL на KOL.

    Установка KOL-MCK

    Скачать библиотеки KOL-MCK необходимо зайти на официальный сайт проекта, в раздел Загрузки: http://kolmck.net/r_kolmck.htm (возможно у вас будут проблемы с отображением текста на сайте, поэтому, если что, переключите кодировку страницы на Windows-1251).

    Обычно. ссылки на сайте постоянные, поэтому я выделю основные, файлы которых нам нужно скачать:
    1. Основной пакет KOL;
    2. KOL-unicode;
    3. Основной пакет MCK;
    4. Библиотеки поддержки использования try..except..finally..end в проектах KOL;
    5. Книга по KOL-MCK (не раз будет вашим незаменимым помощником при написании проектов);

    P.S. Замечание: если что-то не найдется в книге, посматривайте в исходник KOL.pas - там вы найдете ответы на почти все ваши вопросы. Если уж нет: задавайте сюда - постараюсь ответить.

    Итак, вы скачали все указанные выше ссылки. Теперь займемся установкой.
    1) Распакуйте все файлы из архивов в какую-нибудь папку, например, в "c:\kolmck".

    2) Откройте Delphi, зайдите в меню Tools->Environment Options. В этом окне перейдите на вкладку Library, и нажмите на кнопочку, которую я отметил зеленым:
    [​IMG]

    Появится такое окошко:
    [​IMG]

    В нем напишите путь к папке с KOL, и нажмите Add. Окна эти можно закрывать.

    3) Щелкните по меню: File->Open.... Перейдите в каталог, в который вы распаковали архивы. Выберите там файл MirrorKOLPackageDXX.dpk, где XX номер версии Delphi. Я выберу D7. Появится окно установки/компиляции/сборки пакета. Обязательно смотрите, чтобы в списке Requires, было designide.dcp.
    [​IMG]

    Жмите кнопку Install. Должна появиться вкладка KOL. Все, теперь все окна и проекты можно закрывать (если предлагает сохранить изменения в проекте MirrorKOLPackageDXX.dpk, соглашайтесь). Желательно закрыть и открыть Delphi, чтобы все принялось!))

    Создание первого проекта на KOL-MCK

    Как обычно, жмем File->New->Application. Сразу же сохраните весь проект куда-нибудь. *.pas файлы называйте так, какими вы хотите их видеть в конечном проекте. А вот dpr-файл наоборот - не нужно сейчас указывать то имя, которое будет использовано для проекта. Пускай это останется Project1.dpr. Пускай свойство Name у главной формы остается какое есть, не меняйте его.
    Теперь переходим на вкладку KOL и ищем компонент KOLproject, кидаем его на форму.
    [​IMG]

    Свойство компонента, которое нам сейчас нужно изменить: ProjectDest. Сюда вы должны написать имя dpr-файла (без расширения dpr), которое и станет именем вашего проекта. Я написал: firstkol. Теперь ищем еще один компонент KOLForm, и кидаем его на форму тоже. Имя компоненту можете дать какое хотите, но это не будет именем вашей главной формы. Имя формы устанавливается через свойство FormName компонента KOLForm. (На будущее: менять все свойства главной формы нужно менять только через этот компонент). Теперь сохраните проект, и закройте его. Перейдите в папку, в которую вы сохраняли файлы проекта, и удалите там все файлы, имя которых начинается с Project1. Они нам больше не понадобятся. После этого открываем новый dpr-файл - firstkol.dpr.
    После первого открытия файл проекта немного изменится, поэтому снова нажмите Save All.

    Попробуйте откомпилировать этот проект. Должны появиться три ошибки, если вы меняли стандартное имя формы на свое через свойство FormName. Исправляется все очень просто:
    Было приблизительно так:
    Код:
    var
      frmMain {$IFDEF KOL_MCK} : P[B][I]Form1[/I][/B] {$ELSE} : TfrmMain {$ENDIF} ;
    
    {$IFDEF KOL_MCK}
    procedure New[B][I]Form1[/I][/B]( var Result: P[B][I]Form1[/I][/B]; AParent: PControl );
    {$ENDIF}
    а вы должны исправить на такой код:
    Код:
    var
      frmMain {$IFDEF KOL_MCK} : P[B]frmMain[/B] {$ELSE} : TfrmMain {$ENDIF} ;
    
    {$IFDEF KOL_MCK}
    procedure New[B][I]frmMain[/I][/B]( var Result: P[B][I]frmMain[/I][/B]; AParent: PControl );
    {$ENDIF}
    где выделенное жирным курсивом - имя формы, которое вы установили через свойство FormName.

    Снова пробуйте компилировать, и, оп-ля! Все готово! Посмотрите на размер готового exe-файла:
    23 КБ (без сжатия).
    Для сравнения: размер готового ехе-файла нового проекта на VCL - 354,5 КБ.
    Круто, не правда ли?!=)

    Hello, World!

    Не будем отступать от канонов программирования, и поздороваемся с миром! Скинем с вкладки KOL на форму кнопку (значок с надписью OK). Щелкнем по ней двойным щелчком.

    На KOL и VCL) используется одна и та же команда:
    Код:
    ShowMessage('Hello, World!');
    Компилируем проект. Получаем такие размеры файлов:
    KOL: 24 КБ;
    VCL: 379,5 КБ;

    Еще приведу другие команды вывода сообщений, которые можно использовать в своих проектах:
    [+] Цитата из KOL.pas (развернуть)
    Код:
    [B]function MsgBox( const S: KOLString; Flags: DWORD ): DWORD;[/B]
    {* Displays message box with the same title as Applet.Caption. If applet
       is not running, and Applet global variable is not assigned, caption
       'Error' is displayed (but actually this is not an error - the system
       does so, if nil is passed as a title).
       |<br>&nbsp;&nbsp;&nbsp;
       Returns ID_... result (correspondently to flags passed (MB_OK, MBYESNO,
       etc. -> ID_OK, ID_YES, ID_NO, etc.) }
    [B]procedure MsgOK( const S: KOLString );[/B]
    {* Displays message box with the same title as Applet.Caption (or 'Error',
       if Applet is not running). }
    [B]function ShowMsg( const S: KOLString; Flags: DWORD ): DWORD;[/B]
    {* Displays message box like MsgBox, but uses Applet.Handle as a parent
       (so the message has no button on a task bar). }
    [B]procedure ShowMessage( const S: KOLString );[/B]
    {* Like ShowMsg, but has only styles MB_OK and MB_SETFOREGROUND. }

    [свернуть]


    Для справки:
    Практически все команды преобразования типов переменных в KOL переименованы.
    Например, IntToStr теперь называется Int2Str, и т.д. Просто вместо слова To пробуйте вставить двойку.


    Файловые потоки и потоки памяти (PStream)

    KOL предоставляет нам огромные возможности по работе с файловыми потоками, и потоками памяти. Разберем основные функции.

    Для того, чтобы объявить переменную для потока, достаточно объявить переменную типа PStream. Это универсальный тип, который подходит и под потоки памяти, и под потоки файловые.

    На все той же кнопке объявим переменную типа PStream.
    Код:
    [B]var[/B]
    strTest: [B]PStream[/B];
    Теперь вызовем создание потока. Команды могут быть следующими:
    Код:
    strTest:=[B]NewReadFileStream[/B]('file path');
    strTest:=[B]NewWriteFileStream[/B]('file path');
    strTest:=[B]NewFileStream[/B]('file path',fmInput);
    strTest:=[B]NewFileStream[/B]('file path',fmOutput);
    strTest:=[B]NewFileStream[/B]('file path',fmInOut);
    strTest:=[B]NewReadWriteFileStream[/B]('file path');
    strTest:=[B]NewMemoryStream[/B];
    * NewReadFileStream - открывает указанный файл для чтения;
    * NewWriteFileStream - открывает указанный файл для записи;
    * NewFileStream - создает файловый поток с указанным режимом.
    * NewMemoryStream - создает поток на памяти;

    В KOL есть небольшие отличия в команде перехода по файлу Seek. Точнее в ее режимах. Здесь они представлены так: spBegin, spCurrent, spEnd; Так же имеются возможности по записи определенных типов данных в файл (например, строковых. Этого нет в VCL). Рассмотрим это подробнее.

    Создадим файловый поток для записи.
    Код:
    strTest:=[B]NewWriteFileStream[/B]('test.txt');
    Теперь команда записи строки:
    Код:
    strTest.[B]WriteStr[/B]('Hello, World!');
    Для записи числа (первый параметр число, второй - размер числа в байтах - максимум 4):
    Код:
    strTest.[B]WriteVal[/B]( 10, 3);
    Данная команда запишет число 10 (не в строковом виде) в файл, и выровняет его до трех байт.

    Насчет потока на памяти есть своя особенность. Здесь нет метода чтения из файла в память. Поэтому, для того чтобы прочитать из файла в память нужно сначала открыть файловый поток на чтение, потом создать поток на памяти, и воспользоваться такой командой:
    Код:
    function [B]Stream2Stream[/B]( Dst, Src: PStream; Count: TStrmSize ): TStrmSize;
    В первом параметре указывается целевой поток, в который нужно скопировать данные, во втором - исходный поток. из которого будем брать данные, ну и третий - размер данных для копирования.
    Итого, для того, чтобы скопировать весь файл в память объявим еще одну переменную для потока-памяти, создадим его, и скопируем файл данной командой.
    Код:
    var
      strTest, strMem: [B]PStream[/B];
    begin
    strTest:=[B]NewReadFileStream[/B]('test.txt');
    strMem:=[B]NewMemoryStream[/B];
    [B]Stream2Stream[/B](dsrMem,strTest,strTest.Size);
    strTest.Free;
    end;
    Работа с потоками памяти куда быстрее, чем с файлами. Команды перемещения позиции, команды чтения - все во много раз быстрее.

    Работа с реестром

    Наверное, вы помните, что подключая в uses модуль Registry, ваша программа на столько увеличивалась в размерах, что становилось стыдно за VCL.
    В KOL все проще. Давайте посмотрим, что мы можем:

    Очистим текущий код кнопки. Объявим переменную типа HKEY:
    Код:
    [B]var[/B]
      reg: HKEY;
      s: string;
    [+] Список команд для работы с реестром (развернуть) ->
    Код:
    RegKeyOpenRead( k, s ) - открывает ключ реестра на чтение;
    [B]RegKeyOpenWrite[/B]( k, s ) - открывает ключ на запись;
    [B]RegKeyOpenCreate[/B]( k, s ) - создает ключ (если он не был еще создан) и открывает на
    запись;
    [B]RegKeyClose[/B]( r ) - закрывает открытый дескриптор;
    [B]RegKeyDelete[/B]( r, s ) - удаляет подключ с заданным именем;
    [B]RegKeyGetStr[/B]( r, s ) - возвращает значение строкового значения;
    [B]RegKeyGetStrEx[/B]( r, s ) - то же, что и предыдущая функция, но дополнительно понимает
    значения типа REG_EXPAND_SZ (т.е. системные переменные вроде %TEMP%
    замещаются своими значениями из переменных среды);
    [B]RegKeySetStr[/B]( r, s, s1 ) - записывает строковое значение;
    [B]RegKeySetStrEx[/B]( r, s, s1, e ) - то же, что и предыдущая функция, но позволяет записывать
    значения типа REG_EXPAND_SZ;
    [B]RegKeyGetDw[/B]( r, s ) - возвращает значение числового значения (или значения, которое
    может быть интерпретировано как числовое);
    [B]RegKeySetDw[/B]( r, s, i ) - записывает числовое значение;
    [B]RegKeyDeleteValue[/B]( r, s ) - удаляет значение;
    [B]RegKeyExists[/B]( r, s ) - проверяет наличие значения;
    [B]RegKeyValueSize[/B]( r, s ) - возвращает размер значения;
    [B]RegKeyGetBinary[/B]( r, s, buf, n ) - читает бинарное значение в буфер;
    [B]RegKeySetBinary[/B](  r, s, buf, n ) - записывает бинарное значение;
    [B]RegKeyGetDateTime[/B]( r, s ) - читает значение типа дата/время;
    [B]RegKeySetDateTime[/B]( r, s, d ) - записывает значение типа дата/время;
    [B]RegKeyGetValueTyp[/B]( r, s ) - возвращает тип значения;
    [B]RegKeyGetValueNames[/B]( r, list ) - перечисляет имена всех значений в указанном списке
    типа [B]PStrList[/B];
    [B]RegKeyGetSubKeys[/B]( r, list ) - перечисляет все подключи в указанном списке PStrList.

    [свернуть]


    Теперь попробуем прочитать из реестра что-нибудь. Например, путь к каталогу с файлом hosts и изменим его.
    Код:
    reg:=[B]RegKeyOpenRead[/B](HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\');
    Данная строка открывает данную ветку реестра, и присваивает этот путь переменной reg.
    В отличие от VCL, в KOL - при ошибке доступа, или чтения, не возникает исключение. Просто результат возвратит пустую строку.
    Код:
    s:=[B]RegKeyGetStrEx[/B](reg,'DataBasePath');
    Есть и другая команда: RegKeyGetStr, но она не раскрывает системных переменных типа %SystemRoot%.
    Выведем путь к файлу в сообщении:
    Код:
    [B]ShowMessage[/B](s);
    Ну а теперь изменим этот путь на свой (нужны права администратора):
    Код:
      reg:=[B]RegKeyOpenRead[/B](HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\');
      s:=[B]RegKeyGetStrEx[/B](reg,'DataBasePath');
      [B]RegKeyClose[/B](reg);
      reg:=[B]RegKeyOpenWrite[/B](HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\');
      [B]RegKeySetStr[/B](reg,'DataBasePath','d:\badhosts');
      [B]RegKeyClose[/B](reg);
    Предпоследняя команда запишет в данный ключ реестра путь к папке badhosts, в которую мы можем положить свой файл.

    KOL: 25 КБ;
    Delphi: 361,5 КБ;

    Ini-файлы

    KOL позволяет без больших усилий работать с ini-файлами. Здесь все просто.
    Объявляется переменная таким образом:
    Код:
    [B]var[/B]
     ini: [B]PIniFile[/B];
    Теперь разберем основные команды:
    Код:
    ini:= [B]OpenIniFile[/B]('test.ini');
    Создает (если не указан точный путь, то, по-умолчанию в каталоге Windows), или открывает имеющийся файл test.ini.

    Код:
    ini.Mode:=[B]ifmWrite[/B];
    ini.Mode:=[B]ifmRead[/B];
    Режимы открытия ини-файла.

    Код:
    ini.[B]Section[/B]:='main';
    Указывается секция, с который сейчас нужно работать.

    Код:
    ini.[B]ValueString[/B]('teststr','test string value');
    ini.[B]ValueInteger[/B]('testint',10);
    В зависимости от текущего режима работы с файлом позволяет либо записывать, либо считывать из указанного в первом параметре ключа значение. Если режим ifmWrite - указанное во втором параметре значение запишется в указанный ключ. Если ifmRead - второй параметр будет использоваться как прочитанное значение, в случае если ключ не найден.

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

    Другие замечания...

    Практически все команды, и их параметры, которые нужны для написания вашего проекта на KOL-MCK есть в KOL-MCK исходниках. Просто не стоит лениться, а взять и поискать нужную команду.

    Библиотека KOL-MCK развивается, и, можно сказать, дает новую жизнь Delphi-кодерам, которых воротит от огромнейшего размера исполняемых файлов на VCL. При сжатии (советую WinUpack) получится еще меньший размер конечного файла!

    Теперь ваш приятель не усомниться в том, что файл размером 15 КБ - действительно написал крутой программер, а не тот Вася Пупкин, что предлагал свой вариант проги размером 15 МБ.

    "Для конкурса http://www.xaker.name/forvb/showthread.php?t=22866 "
     
    3 пользователям это понравилось.
  2. Хорошая статья :thx:
    У меня Д7 ругался на отсутствие KOLadd.dcu.
    Скачать можно тут _http://kolmck.net/KOLadd.zip
    На этой странице _http://kolmck.net/r_kolmck.htm у меня у одного ссылка 2.88 совпадает с 3.14?
    ~|~евто|-|,
    Да я понимаю про последовательность, просто для сравнения _http://kolmck.net/r_kolmck.htm(та что в статье это ру зеркало) и _http://kolmck.net/e_kolmck.htm это ен зеркало.Я к тому что в ру совпадают ссылки 2.88 и 3.14.Это к тому что немного кривенькое зеркало, не более.
     
  3. freezek, по ссылке, слева - последняя версия. Справа - список старых версий, в исторической последовательности)
     
  4. Уменьшить размер ехе на KOL-MCK можно еще больше, если использовать замену системных модулей.
    Вот по этой ссылке: http://kolmck.net/sys/SysDcu7.zip

    Распакуйте этот архив куда-нибудь, но не в ту же папку, что и KOL. Пропишите эту папку в свойствах своего проекта (Project->Options->Directories->Search Path).

    После компиляции ехешник уменьшится еще на ~10 КБ.
     
  5. не думал что из дельфи можно такое выжимать...
    ps сам пишу на си:)
     
  6. Я тоже не думал .... ))) Сейчас разбираюсь , что к чему .....
     
  7. Спасибо за статью.
    Есть вопрос: можно ли будет наряду с KOL-MCK использовать VCL компоненты?
     
  8. KaeraK
    Только из вкладки KOL
     
  9. А дополнения никакого нет , что бы можно было всеми компонентами пользоваться ? Неудобно .... )
     
  10. Меня интересуют возможности работы с сетью в KOL, а именно протокол SMTP. Есть одна библиотека KOL-ICS (http, smtp, ping),но она распространяется в виде заголовочных *.pas файлов. Т.е. придётся добавлять в uses имя нужного нам pas-файла, а потом в теле кода делать подключение (не через компонент, как в VCL) :) ?
     
  11. Еще можно KOLHttp и KOL DDE будет заюзать .... Только вот понять бы смысл работы с ними .....
     
  12. Почему же?! Не вводи людей в заблуд)
    Спокойно кидаются компоненты и с обычных вкладок. НО!!!!

    Нахера писать тогда на KOL? Если, подключив один единственный VCL-компонент ты вернешься к тому, с чего начал, а именно - большой размер программы.
    На сайте КОЛ-МСК есть примеры работы с перечисленными протоколами вместе с файлами-примерами (даже есть замена синаптикса). Читай, изучай)
     
  13. Все , спасибо . Вот теперь можно попытаться что-то написать .... )))
    Благодарю
     
  14. OK, спасибо. :)
     
  15. А теперь указывать имя файла в uses и дальше вручную ?
     
  16. Ты о ВЦЛ? Тогда просто кидай компонент на форму.
     
  17. Он имеет ввиду KOL. В библиотеке KOLICS голые pas файлы. Получается нам нужно в корневую папку КОЛ скинуть эти файлы, а потом в юзес объявить нужный нам заголовок и работать с ним? :) Т.е без компонента?
     
  18. Ссылка на KOLICS: http://kolmck.net/Components/network/kolics.zip (именно .zip)
    Да, тогда просто подключить нужные файлы (KOLHttpProt,KOLWSocket) в Uses.
    Там в архиве есть примеры работы с протоколами.
     
  19. Мдэ... Никогда с KOL не работал, и вам, ребята, не рекомендую...

    Использовать такой код... Как-то ссыкатно...
    Первый файл который открыл Server/Unit1.pas
    Первые строки которые меня встретили...
    Код:
    [B]{$IFDEF KOL_MCK}[/B]
    uses Windows, Messages, ShellAPI, KOL 
      [B]{$IFNDEF KOL_MCK}[/B], mirror, Classes, Controls, mckCtrls [B]{$ENDIF}[/B],
      KOLWSocket,WinSock;
    [B]{$ELSE}[/B]
    ....
    [B]{$ENDIF}[/B]
    Дальше даже смотреть не стал...))))

    Покопаюсь на досуге... Исследования свои сюда выложу)))
     
  20. Это поделка автора на коленке, а не продукт. Поэтому и не идет в основных библиотеках, чтобы ты мог исправить! Кладов и МСК тут не при чем. Тем более, я уверен, что Гендальф уже такого не напишет говнокода.

    Денег автору демок за это никто не платил!