Difference between revisions of "KOL"

From Lazarus wiki
m (Tip:)
 
(24 intermediate revisions by 4 users not shown)
Line 3: Line 3:
 
[[File:kolmck.png]]<br>
 
[[File:kolmck.png]]<br>
 
<br>
 
<br>
The Key Objects Library - a.k.a. KOL - is an object oriented framework created by Vladimir Kladov (http://kolmck.net) in 2000.<br>
+
The Key Objects Library - a.k.a. KOL - is an object oriented framework created by Vladimir Kladov ([http://f0460945.xsph.ru/rindex.htm website]) in 2000.<br>
 
It is the successor to the XCL library by the same author.<br>
 
It is the successor to the XCL library by the same author.<br>
The current release as of March 2014 is 3.22.<br>
+
The Mirror Classes Kit - a.k.a. MCK - is a set of visual components to write KOL applications in a visual design way -from within the Delphi IDE.<br>
 +
The current point release is 3.23 for KOL and 3.23 for MCK.<br>
 
New versions appear with Irregular intervals, but the library is currently maintained.<br>
 
New versions appear with Irregular intervals, but the library is currently maintained.<br>
<br>
+
There is an svn repository for KOL and MCK at https://svn.code.sf.net/p/kolmck/code/ which is usually more up to date than the point releases.
 +
<br><br>
 
The main reason creating this library is explained through the dissatisfaction of Vladimir and others towards ever increasing codebloat.<br>
 
The main reason creating this library is explained through the dissatisfaction of Vladimir and others towards ever increasing codebloat.<br>
 
Nobody seemed to care anymore about *efficient* coding.<br>
 
Nobody seemed to care anymore about *efficient* coding.<br>
According to KOL users there a strong correlation between Moore's law and degrading code optimizing efficiency.<br>
+
According to KOL users there a strong correlation between Moore's law and degrading code optimizing efficiency.<br><br>
 +
An MCK project designed in a Delphi IDE can be recompiled with both 32 bit and 64 bit  FPC 2.7.1 or later compilers without change.<br>
 +
This way you can without having to upgrade your Delphi to a recent version:<br>
 +
* obtain a 64 bit version of a project.<br>
 +
* obtain a unicode version of a Delphi project (5-2007) by simply defining -dUNICODE_CTRLS.<br>
 +
* or both!<br><br>
 
<br>  
 
<br>  
 
The framework centers around three basic concepts:<br>
 
The framework centers around three basic concepts:<br>
Line 18: Line 25:
  
 
This has several '''advantages''', some of which are: <br>
 
This has several '''advantages''', some of which are: <br>
* The size of your binary is very tiny, on average more 80% smaller than a VCL/LCL binary, but a factor 100 is not unusual.
+
* The size of your binary is very tiny, on average more than 20 times smaller than a VCL/LCL binary, but a factor 100 or more is not unusual.
 
* KOL binaries (both executables and dll's) have much much faster load times and feel snappier.
 
* KOL binaries (both executables and dll's) have much much faster load times and feel snappier.
 
* KOL is very easy to extend once you understand its concepts. It is a fully object oriented framework
 
* KOL is very easy to extend once you understand its concepts. It is a fully object oriented framework
Line 31: Line 38:
 
* Free Pascal compiler 2.6.4 or later for Win32
 
* Free Pascal compiler 2.6.4 or later for Win32
 
* Free Pascal compiler 2.7.1 or later for Win64
 
* Free Pascal compiler 2.7.1 or later for Win64
* [http://kolmck.net KOL 3.22 or later] for win32
+
* [http://f0460945.xsph.ru/rindex.htm KOL 3.23 or later] for win32
 
* The Mirror Classes Kit a.k.a. MCK for those who want to develop using a visual designer like Lazarus or Delphi.
 
* The Mirror Classes Kit a.k.a. MCK for those who want to develop using a visual designer like Lazarus or Delphi.
* [http://kolmck.net/kol322-x64-unofficial.7z Release preview of KOL 3.22-64] for KOL win32/64
+
* [https://yadi.sk/d/Z0uMP31_67nJY Release preview of KOL 3.23-64] for KOL win32/64
 
* [[KOL-CE|See the KOL CE page]] for win-ce development and requirements.
 
* [[KOL-CE|See the KOL CE page]] for win-ce development and requirements.
 
* Not required, but recommended is a copy of FPC's RTL and/or Delphi's RTL sources
 
* Not required, but recommended is a copy of FPC's RTL and/or Delphi's RTL sources
Line 43: Line 50:
  
 
=== Example ===
 
=== Example ===
Let's start with a simple example. A form, a button and some action.<br>
+
Let's illustrate KOL with a simple example. A form, a button and some action.<br>
 
You will notice that the code resembles that of a LCL/VCL application and basically:<br>
 
You will notice that the code resembles that of a LCL/VCL application and basically:<br>
 
It does exactly the same!<br>
 
It does exactly the same!<br>
Line 49: Line 56:
 
<br>
 
<br>
 
Here's the main program file:<br>
 
Here's the main program file:<br>
<syntaxhighlight>
+
<syntaxhighlight lang="pascal">
 
  program koldemo;
 
  program koldemo;
 
  {This line makes us FPC and Delphi compatible}
 
  {This line makes us FPC and Delphi compatible}
  {$IFDEF FPC}{$MODE DELPHI}{$H+}{$APPTYPE GUI}{$ENDIF}
+
  {$IFDEF FPC}{$MODE DELPHI}{$H+}{$ENDIF}
 +
{$APPTYPE GUI}
 
  uses
 
  uses
 
   Kol,
 
   Kol,
Line 63: Line 71:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
<br>  
 
<br>  
And here is the main unit, again, you will notice it is very similar to LC/VCL code:<br>
+
And here is the main unit, again, you will notice it is very similar to LCL/VCL code:<br>
<syntaxhighlight>
+
<syntaxhighlight lang="pascal">
 
  unit koldemo1;
 
  unit koldemo1;
 
   
 
   
Line 78: Line 86:
 
  PForm1=^TForm1;
 
  PForm1=^TForm1;
 
  TForm1=object(Tobj)
 
  TForm1=object(Tobj)
   Form, Button:pControl;{Note both widgets are of the same type}
+
   {Note both widgets are of the same type}
 +
  Form, Button:pControl;
 
  public
 
  public
 
   {The message handler for our Button}
 
   {The message handler for our Button}
   procedure ButtonClick(Sender:PObj); {The message handler for our Button}
+
   procedure ButtonClick(Sender:PObj);  
 
  end;
 
  end;
 
   
 
   
Line 102: Line 111:
 
     Button.OnClick := ButtonClick;
 
     Button.OnClick := ButtonClick;
 
     { The applet variable is the Application object
 
     { The applet variable is the Application object
       Assigning the main for to it assigns the main message loop to the form.}
+
       Assigning the main form to it assigns the main message loop to the form.}
 
     Applet:=Form;
 
     Applet:=Form;
 
     Form.Add2AutoFree(Result);
 
     Form.Add2AutoFree(Result);
Line 110: Line 119:
 
  procedure TForm1.ButtonClick(Sender: PObj);
 
  procedure TForm1.ButtonClick(Sender: PObj);
 
  begin
 
  begin
     MsgOk('Ouch!');
+
     ShowMessage('Ouch!');
 
  end;
 
  end;
 
   
 
   
Line 118: Line 127:
 
So what's so special about it?<br>
 
So what's so special about it?<br>
 
Well, for one, compile this and look at the executable size.<br>
 
Well, for one, compile this and look at the executable size.<br>
A similar program, Form + Button + ShowMessage compiled with Delphi 7 is '''394 Kilobytes''' and it gets worse for progressive newer versions of Delphi:2.267 XE7-32, 3.672 XE7-64<br>
+
A similar program, Form + Button + ShowMessage compiled with Delphi 7 is '''394 Kilobytes''' and it gets much worse for progressive newer versions of Delphi:2267 Kilobytes XE7-32, 3672 Kilobytes XE7-64<br>
Compiled with Delphi 7 it renders an executable of '''20 Kilobytes''' with Delphi 7 (36 XE7-32, 69 XE7-64). That is almost '''20 times smaller than the same D7 VCL, 62 times smaller than XE7-32 VCL and 53 times smaller than XE7-64 VCL!'''<br>
+
For comparison: the KOL version compiled with D7 is '''156''' times smaller than the VCL version compiled with XE7.<br>
 +
<br>
 
Compiled with PPC386 it renders an executable of 48128 bytes. Compiled like:<br>
 
Compiled with PPC386 it renders an executable of 48128 bytes. Compiled like:<br>
 
  ppc386 -Mdelphi -CX -XX -Xs -Os koldemo.dpr  
 
  ppc386 -Mdelphi -CX -XX -Xs -Os koldemo.dpr  
Line 125: Line 135:
 
  ppcx64 -Mdelphi -Rintel -CX -XX -Xs -Os koldemo.dpr
 
  ppcx64 -Mdelphi -Rintel -CX -XX -Xs -Os koldemo.dpr
 
The above examples are for an ANSI application. To compile a UNICODE application, simply add the UNICODE_CTRLS define, like:
 
The above examples are for an ANSI application. To compile a UNICODE application, simply add the UNICODE_CTRLS define, like:
  ppcx64 -Mdelphi -Rintel -dUNICODE_CTRLS -CX -XX -Xs -Os
+
  ppcx64 -Mdelphi -Rintel -dUNICODE_CTRLS -CX -XX -Xs -Os koldemo.dpr
Note that especially for 64 bit, FreePascal renders consistently smaller code than its expensive cousin.<br>
+
Note that especially for 64 bit, Free Pascal renders consistently smaller code than its expensive cousin.<br>
Also note that 32 bit FreePascal has a slightly bigger runtime payload than its cousin. The size difference disappears when you application is more complex.
+
Also note that 32 bit Free Pascal has a slightly bigger runtime payload than its cousin. The size difference disappears when your application becomes more complex.
  
 
== Tip: ==
 
== Tip: ==
 
For size, KOL defaults to an ugly system font.
 
For size, KOL defaults to an ugly system font.
 
Here are multiple ways to remedy that:
 
Here are multiple ways to remedy that:
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal">
 
  {Add this code after the NewForm Function}
 
  {Add this code after the NewForm Function}
 
  {Release the font}
 
  {Release the font}
Line 139: Line 150:
 
  Form.Font.AssignHandle(GetStockObject(DEFAULT_GUI_FONT));
 
  Form.Font.AssignHandle(GetStockObject(DEFAULT_GUI_FONT));
 
</syntaxhighlight>
 
</syntaxhighlight>
The second method is slightly more involved, but is the [http://msdn.microsoft.com/en-us/library/windows/desktop/dd144925%28v=vs.85%29.aspx| MSDN] recommended way:
+
 
<syntaxhighlight>
+
The second method is slightly more involved, but is the [http://msdn.microsoft.com/en-us/library/windows/desktop/dd144925%28v=vs.85%29.aspx |MSDN] recommended way:
 +
 
 +
<syntaxhighlight lang="pascal">
 
  {Add this function}
 
  {Add this function}
 
  function GetGuiFont:TLogFont;
 
  function GetGuiFont:TLogFont;
Line 152: Line 165:
 
  Form.Font.LogFontStruct :=GetGuiFont;
 
  Form.Font.LogFontStruct :=GetGuiFont;
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
Fonts in KOL are objects of type TGraphicTool. This object can also represent pens and brushes.<br>
 
Fonts in KOL are objects of type TGraphicTool. This object can also represent pens and brushes.<br>
 
We can also create a new GraphicTool object representing the GUI font:
 
We can also create a new GraphicTool object representing the GUI font:
<syntaxhighlight>
+
 
 +
<syntaxhighlight lang="pascal">
 
  {The KOL way to assign the GUI font}
 
  {The KOL way to assign the GUI font}
 
  function GuiFont:PGraphicTool;
 
  function GuiFont:PGraphicTool;

Latest revision as of 01:21, 28 April 2021

Introduction

kolmck.png

The Key Objects Library - a.k.a. KOL - is an object oriented framework created by Vladimir Kladov (website) in 2000.
It is the successor to the XCL library by the same author.
The Mirror Classes Kit - a.k.a. MCK - is a set of visual components to write KOL applications in a visual design way -from within the Delphi IDE.
The current point release is 3.23 for KOL and 3.23 for MCK.
New versions appear with Irregular intervals, but the library is currently maintained.
There is an svn repository for KOL and MCK at https://svn.code.sf.net/p/kolmck/code/ which is usually more up to date than the point releases.

The main reason creating this library is explained through the dissatisfaction of Vladimir and others towards ever increasing codebloat.
Nobody seemed to care anymore about *efficient* coding.
According to KOL users there a strong correlation between Moore's law and degrading code optimizing efficiency.

An MCK project designed in a Delphi IDE can be recompiled with both 32 bit and 64 bit FPC 2.7.1 or later compilers without change.
This way you can without having to upgrade your Delphi to a recent version:

  • obtain a 64 bit version of a project.
  • obtain a unicode version of a Delphi project (5-2007) by simply defining -dUNICODE_CTRLS.
  • or both!


The framework centers around three basic concepts:

  • It uses - some say old school - pascal objects, not classes.
  • Most of the widgets are basically one and the same object. Polymorphism is through constructing functions.
  • It ignores the VCL/LCL, in fact it attempts to replace them.

This has several advantages, some of which are:

  • The size of your binary is very tiny, on average more than 20 times smaller than a VCL/LCL binary, but a factor 100 or more is not unusual.
  • KOL binaries (both executables and dll's) have much much faster load times and feel snappier.
  • KOL is very easy to extend once you understand its concepts. It is a fully object oriented framework

It also has very obvious disadvantages, some of which are:

  • KOL is a framework. It doesn't mix very well with classes and it can't be sensibly mixed with LCL/VCL code because you will loose the size advantage.
  • If you are not familiar with the old Object Pascal paradigm from Turbo Pascal the learning curve can be steep.
  • You will miss some functionality that has become common place, like RTTI, but most of these features are often codebloat and the reason why KOL exists in the first place.
  • Because you are often working on the same object with multiple appearances, it may be confusing that some methods or properties that you can see in the code editor do not apply.

Requirements

  • Free Pascal compiler 2.6.4 or later for Win32
  • Free Pascal compiler 2.7.1 or later for Win64
  • KOL 3.23 or later for win32
  • The Mirror Classes Kit a.k.a. MCK for those who want to develop using a visual designer like Lazarus or Delphi.
  • Release preview of KOL 3.23-64 for KOL win32/64
  • See the KOL CE page for win-ce development and requirements.
  • Not required, but recommended is a copy of FPC's RTL and/or Delphi's RTL sources

Supported targets

  • All 32-bit Windows: from Windows 95 to Windows 8.1.
  • All 64-bit x86_64 from Windows 2000 to Windows 8.1.
  • Windows CE based PocketPC and Smartphones. More information on the KOL CE page

Example

Let's illustrate KOL with a simple example. A form, a button and some action.
You will notice that the code resembles that of a LCL/VCL application and basically:
It does exactly the same!
The main difference is the use of objects and pointer to objects instead of classes and the use of constructing functions instead of constructors.

Here's the main program file:

 program koldemo;
 {This line makes us FPC and Delphi compatible}
 {$IFDEF FPC}{$MODE DELPHI}{$H+}{$ENDIF}
 {$APPTYPE GUI}
 uses
  Kol,
  koldemo1 in 'koldemo1.pas';
 
 begin
  NewForm1( Form1, nil);
  Run(Form1.form);
 end.


And here is the main unit, again, you will notice it is very similar to LCL/VCL code:

 unit koldemo1;
 
 interface
 uses
   Windows, Messages, Kol;
 const
  cps:KolString = 'Kol project in ' + {$IFDEF FPC}'Freepascal '{$ELSE}'Delphi '{$ENDIF} +
     {$IFDEF WIN64}'64 bits '{$ELSE}'32 bits '{$ENDIF} +
     {$IFDEF UNICODE_CTRLS}'Unicode'{$ELSE}'Ansi'{$ENDIF};
 type
 
 PForm1=^TForm1;
 TForm1=object(Tobj)
   {Note both widgets are of the same type}
   Form, Button:pControl;
 public
   {The message handler for our Button}
   procedure ButtonClick(Sender:PObj); 
 end;
 
 procedure NewForm1( var Result: PForm1; AParent: PControl );
 
 var
   Form1:pForm1;
 
 implementation
 
 procedure NewForm1( var Result: PForm1; AParent: PControl );
 begin
   New(Result,Create);
   with Result^ do
   begin
     {The appearance of a widget depends on its creating function}
     Form := NewForm(AParent,cps);
     Button := NewButton(Form,'&Click Me');
     {Attach the MessageHandler}
     Button.OnClick := ButtonClick;
     { The applet variable is the Application object
       Assigning the main form to it assigns the main message loop to the form.}
     Applet:=Form;
     Form.Add2AutoFree(Result);
   end;
 end;
 
 procedure TForm1.ButtonClick(Sender: PObj);
 begin
    ShowMessage('Ouch!');
 end;
 
 end.


So what's so special about it?
Well, for one, compile this and look at the executable size.
A similar program, Form + Button + ShowMessage compiled with Delphi 7 is 394 Kilobytes and it gets much worse for progressive newer versions of Delphi:2267 Kilobytes XE7-32, 3672 Kilobytes XE7-64
For comparison: the KOL version compiled with D7 is 156 times smaller than the VCL version compiled with XE7.

Compiled with PPC386 it renders an executable of 48128 bytes. Compiled like:

ppc386 -Mdelphi -CX -XX -Xs -Os koldemo.dpr 

Compiled with PPCX64 for Windows it renders 65536 bytes. Compiled like:

ppcx64 -Mdelphi -Rintel -CX -XX -Xs -Os koldemo.dpr

The above examples are for an ANSI application. To compile a UNICODE application, simply add the UNICODE_CTRLS define, like:

ppcx64 -Mdelphi -Rintel -dUNICODE_CTRLS -CX -XX -Xs -Os koldemo.dpr

Note that especially for 64 bit, Free Pascal renders consistently smaller code than its expensive cousin.
Also note that 32 bit Free Pascal has a slightly bigger runtime payload than its cousin. The size difference disappears when your application becomes more complex.

Tip:

For size, KOL defaults to an ugly system font. Here are multiple ways to remedy that:

 {Add this code after the NewForm Function}
 {Release the font}
 Form.Font.ReleaseHandle;
 {Assign the default windows GUI font object}
 Form.Font.AssignHandle(GetStockObject(DEFAULT_GUI_FONT));

The second method is slightly more involved, but is the |MSDN recommended way:

 {Add this function}
 function GetGuiFont:TLogFont;
 var Metrics:TNonClientMetrics;
 begin
   Metrics.cbSize := SizeOf(Metrics);
   SystemParametersInfo(SPI_GETNONCLIENTMETRICS, SizeOf(Metrics), @Metrics, 0);
   Result := Metrics.lfMessageFont;
 end;
 {And call it after the form creation}
 Form.Font.LogFontStruct :=GetGuiFont;

Fonts in KOL are objects of type TGraphicTool. This object can also represent pens and brushes.
We can also create a new GraphicTool object representing the GUI font:

 {The KOL way to assign the GUI font}
 function GuiFont:PGraphicTool;
 var Metrics:TNonClientMetrics;
 begin
   Result := NewFont;
   Metrics.cbSize := SizeOf(Metrics);
   SystemParametersInfo(SPI_GETNONCLIENTMETRICS, SizeOf(Metrics), @Metrics, 0);
   Result.LogFontStruct := Metrics.lfMessageFont;
 end;
 {We can now assign the new font to the Form's font property}
 Form.Font.Assign(GuiFont);

And this is the result: kolscreenshot.png