Delphi and Lazarus
Trekking and Events
Blog and Forum
Čeština English
Main menu
Delphi and Lazarus
Top downloads
KGrid (23598x)
KControls Component Suite (20248x)
KHexEditor (5278x)
KIcon (2584x)
CAN Event Manager (466x)

KControls Component Suite

KControls is a freeware distribution, a flagship of tkweb. It contains all of my published components for Delphi and Lazarus. All controls have been written with the aim to become both cross-IDE compatible (Delphi/C++Builder VCL and Lazarus LCL) and cross-platform compatible in Lazarus. There are some exceptions to this scheme, see below.

Components included
TKGrid - powerfull control for working with table data, replacement for TStringGrid and TDrawGrid - full compatibility and lot of new features
TKDBGrid - control for working with database tables, possible replacement for TDBGrid
TKMemo - native replacement for TMemo/TRichEdit - written from scratch, great features, full RTF support etc.
TKHexEditor - another useful control for binary file editing
TKIcon - powerfull component for working with icons and cursors (files *.ico and *.cur, works only on Windows)
TKPrintPreview - control for displaying print preview, it is part of KControls built in printing capabilities, every visual control supports printing and previewing
TKPrintPreviewDialog - nonvisual component - dialog - for an easy print preview implementation
TKPrintSetupDialog - nonvisual component - dialog - for an easy implementation of printing preferences
TKCustomControl - a base for your visual controls, for which you want to implement e.g. printing and previewing capabilities in Delphi or Lazarus (just 2 short functions to write).
TKNumberEdit - edit control to input numbers in various formats
TKFileNameEdit - edit control to input file names
TKLinkLabel - label to show clickable link
TKGradientLabel - label with gradient background
TKLog - component for event logging
TKPercentProgressBar - custom drawn progress bar which shows actual percentage of the progress
TKBrowseFolderDialog - wrapper for the standard Windows API browse for folder dialog (works only on Windows)
TKBitBtn - like TBitBtn - draws PNG and alpha channel correctly in Delphi, has WordWrap property, works in Lazarus as well
TKColorButton - just another button to pick color
TKPageControl - page control written from scratch with custom painted tab panel, has tab icons and close button icon


KControls is provided free on 'as is' basis, with complete source code. However, it is licensed software. More information about license can be found in source file headers.

All controls support Delphi and Lazarus IDEs fully. But there are some exceptions: TKIcon and TKBrowseFolderDialog work only on Windows and printing and previewing might not work in some widgetsets in Lazarus.

Note: In Delphi only VCL is supported. FMX will never be supported.


If you want to donate for further development of KControls just think about building your own photovoltaics and using the WATTrouter device produced by our company. You will save lots of energy and it will be the best donation to me you can make!

Screenshots (click the images to enlarge)

KControls components (Windows Vista)KControls components (Windows XP/GTK2runtine)
KMemo rich text editor showing the KMemo manual.KMemo rich text editor showing more complex sample RTF document.

Repository - development versions

You may now download newest development version at bitbucket. Please download and try this version if something is not working in the official release listed below.

Downloading KControls

Important note: When installing the packages in Delphi XE2 and later you must add "Vcl;Vcl.Imaging" to Unit Scope Names in Delphi Options/Library! Otherwise the packages won't compile!

FileVersionNumber of
Available for:Changes
kcontrols_1.7.zip1.77378Delphi 7+,Lazarus 1.2.2+, C++Builder 2007+support for RAD Studio XE8, major work on TKMemo which is already usable, bugfixes...
kcontrols_1.6.zip1.62740Delphi 7+,Lazarus 1.2.2+, C++Builder 2007+support for RAD Studio XE6, Columns property in TKDBGrid, bugfixes...
kcontrols_1.5.zip1.5387Delphi 6+,Lazarus 1.2.2+, C++Builder 2007+new components TKMemo, TKBitBtn, TKColorButton, some bugfixes...
kcontrols_1.4.zip1.41032Delphi 6+, Lazarus 0.9.29(SVN#21827)+, C++Builder 2007+support for RAD Studio XE3-XE5, new components etc.
kcontrols_1.3.zip1.32745Delphi 6+, Lazarus 0.9.29(SVN#21827)+, C++Builder 2007+support for RAD Studio XE2
kcontrols_1.2.zip1.23115Delphi 6+, Lazarus 0.9.29(SVN#21827)+, C++Builder 2007+cumulative update (KGrid 1.7, KHexEditor 1.5, KIcon 2.2)
kcontrols_1.1.zip1.11118Delphi 6+, Lazarus 0.9.29(SVN#21827)+, C++Builder 2007+cumulative update (KGrid 1.6, KHexEditor 1.4, KIcon 2.1)
kcontrols_1.0.zip1.01733Delphi 6+,Lazarus 0.9.29(SVN#21827)+initial release (KGrid 1.5, KHexEditor 1.4, KIcon 1.9)

If you have a question you may ask below and I will probably answer it, after some time.


Home | Software | Delphi and Lazarus | Trekking, travelling | Sport | Blog

Search in comments: 
inserted: 2018-02-15 08:22:35   Reply...
From: см
I have troubles with ScrollBy (example below) in Lazarus 1.8.
1. If I try to use KMemo1.ScrollBy(0,20,True); my app does not compile, saying
„Error: Wrong number of parameters specified for call to "ScrollBy"‟.
If I press alt+arrow_up in the IDE I am taken to ScrollBy defined in kmemo.pas
2. If I remove last parameter and try to use KMemo1.ScrollBy(0,20); nothing happens when executing the code (no scroll is done, I tried +20 and -20).
If I press alt+arrow_up in the IDE I am taken to ScrollBy defined in Controls.pp.

I guess something goes wrong with visibility of ScrollBy?

procedure TForm1.Button1Click(Sender: TObject);
  i: integer;
  for i:=1 to 50 do
inserted: 2018-02-13 19:13:30   Reply...
From: RedOctober
I am just starting to use Lazarus after having used Delphi for 15 years. I'm using the Lazarus "Fix" version which is 1.8.1. In the Lazarus forum, some one suggested I use KMemo. I downloaded your v1.7 and tried to compile and the compiler complained about the UTF8Copy (and Character) functions. I added the unit LazUTF8 to the necessary "Uses" clauses and it compiled and installed your components. My next step was to uninstall the v1.7 then install your latest version from bitbucket. The v1.7.1 from bitbucket has a .lpk but the Package installer complains that there are no registered components in it, so the Lazarus IDE will bloat up, and no components will be visible on the componenent palette. I proceded with the install then uninstalled. (I did notice that the compiler did not complain about any UTF8 stuff, which was my original goal installing your latest version from bitbucket)

My question is: How do I install your latest .lpk from bitbucket so that the components show up on the component palette? Thanks in advance for any help you can provide.
inserted: 2018-02-14 22:13:28   Reply...
From: tk
Please use the trunk, download from bitbucket. And you should be fine with compilation. 1.7 is rather historic snapshot and might not work with newer Delphi/Lazarus. Unfortunatelly I have no time now to push the development towards 1.8. I am very busy with my company and other things now...
inserted: 2018-02-08 15:09:23   Reply...
From: см
Hi Tk,
Since the very beginning I have had problems with tables staying locked.
I think I have finally found the solution and possibly the reason for that.

My code was someting like:

Now it is something like:
  if KMemo1.Blocks.UpdateUnlocked= true then

Looking in the code of TKMemo it occurs that locking state is stored by an integer FUpdateLock, and each time LockUpdate is called FUpdateLock is increased.
Is there (still) a reason for that behaviour (using INT instead of BOOL), or shall I write in wiki, that LockUpdate shall be called only this way:
    „if KMemo1.Blocks.UpdateUnlocked= true then KMemo1.Blocks.LockUpdate;‟?
inserted: 2018-02-09 08:24:22   Reply...
From: см
Well, it not so hard to see why FUpdateLock is a counter.
I have modified TKObjectList.UnLockUpdate in Kfunctions.pas. I think it should work, at least it did not crash (I have already added „if ...updateunlocked‟ in my code, so I cannot tell without undoing that).
I wonder if the default value should be True or False. „False‟ will require no other changes in the source of KMemo, „True‟ seems more fail-safe for the end userс.

//If FullUnlock=True KObjectList gets unlocked, disregarding the value of FUpdateLock
procedure TKObjectList.UnLockUpdate(FullUnlock : boolean= False);
  if FUpdateLock > 0 then
    if FullUnlock
      then FUpdateLock:=0
      else Dec(FUpdateLock);
    if FUpdateLock = 0 then
inserted: 2018-02-14 22:10:30   Reply...
From: tk
I am not sure what you mean or where the problem is. Each LockUpdate should be paired with UnlockUpdate. If forgotten somewhere, the respective blocks stay locked and you might get unpredictable behavior. If so, you should review your code and try to find where UnlockUpdate is missing. Always use try-finally clause:


And you should be fine.
inserted: 2018-02-15 08:04:31   Reply...
From: см
Actually I am making a proposal for you to consider adding a parameter FullUnlock in UnlockUpdate, as seen in the code in my previous post. This will be useful when one needs to make sure that Unlock will happen (instead of looping until .UpdateUnlocked=True)

I will add this info in the Lazarus wiki.
inserted: 2018-02-01 09:43:39   Reply...
From: andrey
Hello! Is it possible to set the alignment of the text at column title (KDBGrid), separately from the alignment in the data cells? Is there some suitable property, like "TitleAlignment" ?
inserted: 2018-01-28 14:52:35   Reply...
From: Gicla22
Hello TK and thanks first of all.
I recently downloaded latest KControls version and tried to use with Lazarus 1.8 but when compiling projects I get the below error:

Warning: other unit files search path (aka unit path) of "KControlsLaz 1.7"
contains "C:\lazarus\components\KControls_1.7\source", which belongs to package "KControlsBase"
Warning: other unit files search path (aka unit path) of "KControlsBase 1.7" contains "C:\lazarus\components\KControls_1.7\source", which belongs to package "KControlsLaz"

I tried to uninstall, clean up directories and reinstall but no way.
How can I fix it?
inserted: 2018-02-14 22:04:45   Reply...
From: tk
IMO there is a bug in Lazarus causing these warnings.
There is no reason why different packages could not take units from the same directory.
At least these warnings should be optional, an option to turn them off should exist in package project.

I asked myself on the forum some time ago but no answer.,34822.msg229128.html#msg229128

I had no time to file a bug report.
inserted: 2018-01-29 06:18:04   Reply...
From: Davo
Gicla22, its actually only a warning, not an error. Its been there for a while now and does no do any harm. I confess I have been ignoring it.

inserted: 2018-01-29 08:45:37   Reply...
From: Gicla22
Thanks Davo for the info.
In fact I continued to debug my code and found that the problem I have it's not related to KControls.
inserted: 2018-01-26 04:29:42   Reply...
From: Davo
Hi TK, you have not heard from me for a while (good, eh ?). Been building a replacement for Tomboy Notes in Pascal and, of course, KMemo.

KMemo is such a product ! Thanks

However, I am having an issue with cut, copy and paste. Two separate issues in fact. Firstly, you sensibly respond to Ctrl-[xcv] but on a Mac, because its a Mac, it should be another shift key, the "Command" key. Stupid but true !

The other issue is more subtle. On Linux and Windows the cut, copy and paste do not work when an app is first started. It takes a couple of repeated cycles and then does work fine for the run time of the app. Same result whether you use the (eg) Ctrl-v or a menu driven call to KMemo1.ExecuteCommand(ecPaste);

To further complicate, it does work first up occasionally. And, yes, I can demo this in a simple app. Once it starts working, its OK, so I am wondering if there is some initialization required I don't know about ?

I'm using head version of KControls (couple of months old) and Lazarus 1.8

inserted: 2018-01-27 11:53:41   Reply...
From: tk
1. The Command key on MAC: I am not a MAC expert but I think even Lazarus itself does not respond to this key and it IMO can't because there is no ssCommand modifier in Classes.TShiftStateEnum. To test on MAC I just use a virtual MAC where I remapped all keys to suit my Windows keyboard and default Windows behavior.

2. Cut, copy and paste work fine for me in the KMemo demos (all supported platforms). Did you try with these demos? If yes then maybe Lazarus 1.8 is buggy (but this I doubt even though I always use Lazarus trunk) or you have another problem in your PC like a virus, hardware problem etc. If no then there is problem in your program using KMemo.
inserted: 2018-01-28 00:35:36   Reply...
From: Davo
Thanks for the Mac fix, will have a go at it today.

Yes, I have seen the copy and paste issue in KmemoEditorLaz. But a lot less often (??). Spent an hour or so this morning trying to identify a pattern but nothing clear. But an impression that I see the problem in my simple demo only when my main app is running. Conversely, I see the problem lot less in my main app when your demo IS running ! I suspect my current data is more noise than data ...

Can you suggest where I should set a watch to see (eg) ctrl-v being handled ?

I am quite sure I don't have a hardware issues and pretty confident about viruses (linux), its a code issue and probably in my code. I do intercept keystrokes going to KMemo to do thinks like check for backspaces around bullets and some other application specific stuff.

Thanks for your help !
inserted: 2018-01-27 12:34:29   Reply...
From: tk
Reply to myself ad 1) Actually found this now:
Here the ssMeta should be connected to the Apple Command key. I've added at least the 3 basic commands to the default keymap.
inserted: 2018-01-29 06:15:11   Reply...
From: Davo
Some embarrassment when I realized I was still using Lazarus V1.8rc3 on my build machine. Its setup to do a number of cross compiles and I have been lazy with updating it.
So (real) lazarus 1.8 and the current head version of KControls seems to have fixed my copy and paste errors. Of course, I'm not sure which...

And, yep, you have fixed the Apple's (bless them) rather unique problem with Command rather than Control key to copy etc

Thanks TK.
inserted: 2018-01-21 14:53:54   Reply...
From: velas
Hello. Excuse for the wrong English - it is machine translation.
 Lazarus 1.6.4, KControls 1.7. Whether KGrig.FixsedRows TKGrid title printing on each new page of the report (on one page is not located) is possible. Whether it is possible to place several object TKGrid variables in one report.
inserted: 2018-01-27 11:23:47   Reply...
From: tk
Fixed rows only appear at the first page now.

For several TKGrids in one page you would need to write your own printing algorithms.
inserted: 2018-01-21 13:50:30   Reply...
From: fedor

I found error at TKCustomGrid.FindRow
There are
while Index < ColCount do
while Index < RowCount do

So sometimes FindRow return -1 (if ColCount < RowCount)
inserted: 2018-01-27 11:15:53   Reply...
From: tk
Thanks will be fixed in next commit.
inserted: 2018-01-12 21:19:48   Reply...
From: budboy

procedure TForm1.KGrid1EditorCreate(Sender: TObject; ACol, ARow: Integer;
  var AEditor: TWinControl);
  If (ACol = 0) or (ARow = 0)
    AEditor := TEdit.Create(nil);

  If (ACol = 1) and (ARow = 1)
     AEditor := TComboBox.Create(nil);
     TComboBox(AEditor).Style := csDropDown; // cannot set height on Win!

  If (ACol = 2) and (ARow = 1)
     AEditor := TCheckBox.Create(nil);
     TCheckBox(AEditor).Font.Color := clRed; // applies only without OS themes (in Delphi)

procedure TForm1.FormCreate(Sender: TObject);
  KGrid1.Cells[1,0] := 'ComboBox';
  KGrid1.Cells[2,0] := 'CheckBox';

That's what I wrote, and at startup you do not see what's in the cell.
If I turn on the checkbox, switch to another cell, then back, it will not stay on.
inserted: 2018-01-21 14:12:48   Reply...
From: fedor
see example of usind events "OnEditorDataFromGrid" and "OnEditorDataToGrid" in demos
inserted: 2018-01-09 19:03:55   Reply...
From: hoyosfelix
Thanks for those components you released for the community.
I'm testing the KGrid component with Lazarus 1.4.4 and Firebird database.
When I show numeric values within the TKDBGrid the columns show number with a question mark infront of it:

? 1.400
? 0
? 21

I would like to know how to change the display format for numeric value.

Thanks again.
inserted: 2018-01-27 11:09:18   Reply...
From: tk
Hard to say what's wrong. Since I don't use databases at all now, you would have to debug TKDBGrid and find out the cause, yourself.
inserted: 2018-01-03 12:01:32   Reply...
From: см
Hi TK and Happy new year!
Similar to discussion from 2017-09-12:

kmemo.pas contains the following line:
cDefaultWordBreaks = [cNULL, cSPACE, '/', '\', ';', ':', '(', ')', '[', ']', '.', '?', '!'];...
Should apostrophe (') also be added?
inserted: 2018-01-03 14:26:02   Reply...
From: см
Hm, actually the issue is that when I double click on a text wrapped in apostrophes it gets selected together with them.
This should not be an issue of cDefaultWordBreaks, since wrapping on an opening apostrophe is a nonsense.
inserted: 2018-01-04 10:58:43   Reply...
From: tk
I think it is correct now. Apostrophe should not be a word break. For example the word: isn't. It is one word. Surely there might be exceptions in different languages but this goes beyond the scope of KMemo.
inserted: 2018-01-04 11:21:57   Reply...
From: см
Does selection of words on double click depend on cDefaultWordBreaks or on something else?
I tried
Asfsadf 'safdsafsafd' afsadf
Asfsadf "safdsafsafd" afsadf
in Wors, Lazarus IDE, in a text editor and in the web-page of TKWeb. I all of them double-clicking on safdsafsafd selectes the text withput the quotation marks/ apostrophes.
TKMemo seems to be the only exception.
inserted: 2018-01-08 22:47:06   Reply...
From: tk
I see now. Quotation marks (single or double) are not word breaks. There must be some other logic in Word, browsers etc. which is not yet implemented in KMemo.

Actually the behavior between different programs varies here.
Example: you've
MS Word correctly selects entire contraction(irrelevant where you double click), Firefox selects either 'you' or 've' on a double click.

Afaik for both single quotation marks and English contractions, possessives etc. the same character (U+0027) is used, which means there must be some extra logic to distinguish them.
inserted: 2018-02-09 15:28:46   Reply...
From: edvoigt
Hi tk,
I think single quotation marks embedded by letters, like in you've or let's. So there is a difference to real quotation.
Thanks for your Work on KControls!
inserted: 2018-01-09 09:46:38   Reply...
From: см
Behaviour like in FF seems fine to me, „I've‟ is quite an exception, maybe they Word has a dictionary for exceptions.
I guess all of them use different character lists for wrapping and for double-click selection.
inserted: 2018-01-10 15:53:03   Reply...
From: см
Currently cDefaultWordBreaks = [cNULL, cSPACE, '/', '\', ';', ':', '(', ')', '[', ']', '.', '?', '!']
This way words might be wrapped at ( and [ which shall not happen.
Probably it would be a good solution to create the Words[..] array according a full list of word breakers (including ()'"„‟«»... etc) and "blacklist" some of them during wrapping, but not during doubleclick.
inserted: 2017-12-12 02:19:10   Reply...
From: DanishMale
I have upgraded to Lazarus 1.8.0 x64 on Windows, when I try to install KControls I get this log and an exit error:

Compile package KControlsLaz 1.7: Exit code 1, Errors: 1, Warnings: 5, Hints: 4
kgraphics.pas(373,15) Warning: An inherited method is hidden by "Clear;"
kgraphics.pas(528,15) Note: Virtual method "Paint;" has a lower visibility (protected) than parent class THintWindow (public)
kgraphics.pas(542,15) Note: Virtual method "Paint;" has a lower visibility (protected) than parent class THintWindow (public)
kgraphics.pas(1079,36) Warning: Symbol "Handle" is deprecated
kgraphics.pas(3020,3) Note: Local variable "TextPtr" is assigned but never used
kgraphics.pas(3052,3) Note: Local variable "TextPtr" is assigned but never used
kmemo.pas(1525,78) Warning: Symbol "CM_SYSCOLORCHANGE" is not implemented
kmemo.pas(1696,14) Warning: An inherited method is hidden by "ScrollBy(LongInt;LongInt;Boolean):Boolean;"
khexeditor.pas(675,78) Warning: Symbol "CM_SYSCOLORCHANGE" is not implemented
kmemortf.pas(4030,10) Error: Identifier not found "UTF8Copy"

I hope you can help adjusting KControls to this new Lazarus version, aas far I have been able to establish is the function UTF8Copy deprecated (
inserted: 2017-12-12 02:32:24   Reply...
From: DanishMale
Ignore this.... found your development version and it compiles perfectly....

Thanks for a GREAT piece of software
inserted: 2017-12-03 17:48:45   Reply...
From: Robert
Is it easy to change TKGrid so it prints pages as columns?
I mean multi column printing like in Acrobat Reader or LazReport.
inserted: 2017-12-05 21:30:35   Reply...
From: tk
I don't know what you mean, please put a screenshot somewhere and provide a link to it here.
inserted: 2017-12-22 00:18:45   Reply...
From: Soner
poFitToPage option is in multi-column-page-print-mode not important.
Multi-column-page ist usefull when kgrid has up to four thin columns and the user wants save paper.
inserted: 2017-12-22 00:01:45   Reply...
From: Soner
I made it but some things are missing. Here is the link with images and modificated files. Maybe you can build it to end. Also I put to the zip KGrid as Treelist, i made it years ago but never used it.!AvJGv-C_3b-WgQoq5d5E9DirKmqL

(The comment above is from me, i don't know why nickname is shown as robert)
inserted: 2018-01-04 10:45:17   Reply...
From: tk
I see now. KGrid does not support this - personally I never needed this.

We also adapted KGrid to behave as treelist, but not as new control, only with available methods and events.
inserted: 2017-11-30 09:22:13   Reply...
From: см
Hi TK,
There is something wrong with „ExecuteCommand(ecGotoXY...‟ and „ClampInView‟.
If I execute it in a table exceeding one page they behave odd (they go to somewhere but the place depends on the position of the cursor in the memo).
Sample code is below.

I have found a workaround for ecGotoXY, but I have no idea how to proeced with „ClampInView‟.

Also, I did not find a way how to scroll the text several lines up, without moving the caret. Is it possible?

unit Unit1;

{$mode objfpc}{$H+}


  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,


  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    KMemo1: TKMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);



  Form1: TForm1;
  MyTable: TKMemoTable;


{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
  MergeSpan: TKCellSpan;
  i,j: integer;
  KMemo1.Blocks.clear ;

  mytable.Cells[0,2].Blocks.AddTextBlock ('2;0');
  mytable.Cells[1,2].Blocks.AddTextBlock ('2;1');
  for i:=0 to 100 do

procedure TForm1.Button2Click(Sender: TObject);
  CellPos: TRect;
    //CellPos.Left:=MyTable.Rows[1].Left; //ecGoto does not works with this code. Possibly a bug?
// KMemo1.ExecuteCommand(ecEditorTop); //If this line is commented ecGotoXY goes to a different polace each time it is executed. If it is not commented, ecGotoXY goes to where it should go.
      KMemo1.ExecuteCommand(ecGotoXY, @CellPos.TopLeft);

inserted: 2017-12-01 23:08:07   Reply...
From: tk
1. There is nothing wrong with those methods, only you need to know how to use them, which is not yet described in the manual/comments.
If you want to move caret to a specific block (what I assume you want) and scroll the memo to show the caret (always) just do:

procedure TForm1.Button2Click(Sender: TObject);
  CellPos: TRect;
  CellPos:=KMemo1.BlockRect(MyTable.Rows[1]); // bounding rectangle of any block in coordinates relative to the memo.
  KMemo1.ExecuteCommand(ecGotoXY, @CellPos.TopLeft); // move the caret to a new position, just like with a mouse click
  KMemo1.ClampInView(nil, False); // scroll the memo to show the caret (needed when the caret position does not change, but the user scrolls the memo with scrollbars)

2. Scrolling the text several lines up, without moving the caret, is possible with a simple trick:

procedure TForm1.Button3Click(Sender: TObject);
  I, OldCaretPos: Integer;
  OldCaretPos := KMemo1.SelEnd; // save old caret position
  for I := 1 to 10 do
    KMemo1.ExecuteCommand(ecUp); // move caret one line up
  KMemo1.Select(OldCaretPos, 0, False); // return the caret where it was

Or if you don't care about lines use ScrollBy. This will scroll like scrollbars do.
inserted: 2017-12-07 12:44:03   Reply...
From: см
Thanks for the help!

„1....just do:

procedure TForm1.Button2Click(Sender: TObject);
  CellPos: TRect;
  CellPos:=KMemo1.BlockRect(MyTable.Rows[1]); // bounding rectangle of any block in coordinates relative to the memo.
  KMemo1.ExecuteCommand(ecGotoXY, @CellPos.TopLeft); // move the caret to a new position, just like with a mouse click
  KMemo1.ClampInView(nil, False); // scroll the memo to show the caret (needed when the caret position does not change, but the user scrolls the memo with scrollbars)

I executed the code, it works fine. Actually ClampInView is not necessery because it seems to be done internally by ecGotoXY.

„2. Scrolling the text several lines up, without moving the caret, is possible with a simple trick:...‟
That also works for me.

„Or if you don't care about lines use ScrollBy. This will scroll like scrollbars do.‟
I could not make ScrollBy work. It seems to do nothing.

My problems is that when I execute ecGotoXY to a line BELOW the current one, the line to which the carret is placed in displayed at the bottom of the page, while I prefer it to be on the top.
I am partially solving the issue with your method in comment „2.‟ but it is tricky, since some lines contain images and tables and are really tall.
inserted: 2017-11-22 01:20:14   Reply...
From: traumschule
Running the application quite often the following message is shown:

Peek !!!

Is this caused by KControls and if so, what does it mean and is there a way to disable it?

inserted: 2017-11-23 09:02:28   Reply...
From: см
You could search the source code of KControls for thje string „peek 111‟. If it is not there, search the reason somewhere else.
inserted: 2017-11-23 13:22:20   Reply...
From: traumschule
Thanks for the hint! I asked because I see this message three times when I open or close a note with tomboy-ng ( and for the user there's no meaning to it.

I was able to disable this message with the following patch. May it be useful to others.

To apply copy the lines below into the file 'hide_peek.patch', if you haven't already, download KControls and apply the patch:
$ curl >
$ unzip
$ cd tkweb-kcontrols-9fab2d710a8c
$ patch source/kcontrols.pas ../hide_peek.patch

From a7613a358829928f822cd396469e252ebedb6898 Mon Sep 17 00:00:00 2001
From: Traumschule Riebau <>
Date: Thu, 23 Nov 2017 13:04:43 +0100
Subject: [PATCH] hide "Peek !!!" message

 source/kcontrols.pas | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/kcontrols.pas b/source/kcontrols.pas
index 1c7e4cc..ce65d2e 100644
--- a/source/kcontrols.pas
+++ b/source/kcontrols.pas
@@ -2112,7 +2112,7 @@ begin
     MessageExists := MessageSearch(Msg.Msg);
     if not MessageExists or not IfNotExists then
- MessagePoke(Msg);
+ //MessagePoke(Msg);
       PostMessage(Handle, KM_LATEUPDATE, 0, 0);
     // resend lost message
inserted: 2017-11-28 22:16:28   Reply...
From: tk
Just tried this app and had no such problem. I compiled against my newest KControls, as usual. Maybe it has been already fixed in this project?

Btw.: Many things get messed up with your patch.
inserted: 2017-11-29 20:49:00   Reply...
From: traumschule
(Is it possible to link to comments on this page?)

Do you use above link for 1.7? Our installer downloads

What do you mean with "many things get messed up"? My patch removes debug output. I am not experienced enough to see how this can mess something up.
inserted: 2017-12-01 22:16:20   Reply...
From: tk
Yes. The tip equals my version now. There is no debug output in KControls. I don't know what you mean. If you disable that line in kcontrols.pas things like delayed updating etc. (used in many controls) stop working.
inserted: 2017-11-21 20:49:59   Reply...
From: traumschule
With current our project fails to compile with lazbuild 1.8.0RC5:

tkweb-kcontrols-e4ec3f5e4b06/source/kgrids.pas(2945,15) Error: (3058) There is no method in an ancestor class to be overridden: "DoAutoAdjustLayout(const TLayoutAdjustmentPolicy;const Double;const Double;const Boolean);"

Any chance to get this fixed in the future? (commenting relevant lines out is a workaround but rather no fix)

Thanks for your work!
inserted: 2017-11-22 00:46:42   Reply...
From: TK
I've commented this out in the trunk.
There is this site talking about DoAutoAdjustLayout but it is unclear to me which LCL version supports/should or will support this.
inserted: 2017-12-10 18:52:02   Reply...
From: RusMikle
Lazarus 1.8 Release

kgrids.pas(2945,15) Error: (3058) There is no method in an ancestor class to be overridden: "DoAutoAdjustLayout(const TLayoutAdjustmentPolicy;const Double;const Double;const Boolean);"

The error has remained.
inserted: 2017-12-10 19:24:45   Reply...
From: RusMikle
in procedure TKCustomGrid.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; const AXProportion, AYProportion: Double; const AScale0Fonts: Boolean);

Parameter - const AScale0Fonts: Boolean - obsolete

to write correctly:
TKCustomGrid.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy; const AXProportion, AYProportion: Double);

inserted: 2018-01-04 10:30:10   Reply...
From: tk
Please use latest bitbucket version. There TKCustomGrid.DoAutoAdjustLayout is commented out - it must compile fine in Lazarus 1.8. I won't change anything here anymore in foreseeable future.
inserted: 2017-11-22 01:13:46   Reply...
From: traumschule
Thanks TK for your fast reply. Maybe we manage to implemented the listed steps to our application.

I just returned to post this patch:

$ cat <<EOF > kgrids.patch
< procedure DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy;
< const AXProportion, AYProportion: Double; const AScale0Fonts: Boolean); override;
> {procedure DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy;
> const AXProportion, AYProportion: Double; const AScale0Fonts: Boolean); override;}
< procedure TKCustomGrid.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy;
> {procedure TKCustomGrid.DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy;
< end;
> end;}
$ patch tkweb-kcontrols-e4ec3f5e4b06/source/kgrids.pas kgrids.patch
inserted: 2017-11-11 13:52:15   Reply...
From: ilias-bk

i try to install the 1.6 version in Delphi 6 and i get o errors about the GetLocaleFormatSettings

inserted: 2017-11-22 00:43:05   Reply...
From: TK
I am sorry but no test/fix will be done for Delphi 6 anymore (as it is rather prehistoric). If 1.6 does not compile in Delphi 6 try older versions and tell me what KControls compiles fine (if any). I'll delete the Delphi 6 support for relevant versions from this site then.
inserted: 2017-11-07 02:55:40   Reply...
From: Davo
Having a 'refresh' issue with KMemo.

My App has grown quite big now, have been working on other aspects recently but just noticed that when I load a some content in KMemo and mark a few hyperlinks in that content, the links are not underlined until I make some arbitrary change to the text. Inserting a space (and removing it) before the links fixes both. Adding something at the end will fix one of the two links ???

I have tried a number of things programaticly such as inserting and removing a space but that does not help. Tried KMemo1.[Refresh, invalidate, repaint, update. blocks.UpdateAttributes] all with no effect.

I have noticed this phenomenon in the past but have been able to fix it by adding and removing a Paragraph marker at the end. Thats not working now.

Is there some way to ask KMemo to refresh itself ?

inserted: 2017-11-07 03:20:20   Reply...
From: Davo
Just cancel that, its a coding error on my part. Sigh ....
inserted: 2017-11-02 20:17:27   Reply...
From: Velas
Hello. Forgive for bad English and obvious questions. КGrid - Question. How to justify the text in Heading of the table and in separate cells? Whether the fixed lines and columns (headings) in any place of the table can settle down?
Thanks in advance.
inserted: 2017-11-07 20:43:06   Reply...
From: tk
You need to do this in OnDrawCell. Search for CellPainter.HAlign on this forum and you'll find a lot of examples.
inserted: 2017-10-25 08:48:02   Reply...
From: см
Hi Tk,
I wonder if you happen to have adding support for images in hyperlinks in your todo list.
You have mentioned some time ago that it should not be too hard.
Previously I had the wrong impression that I have overcome the lack of this feature (yo have helped me on this) but since it ocurred I was wrong I wonder if I should search for another alternative solution.
inserted: 2017-11-07 20:40:22   Reply...
From: tk
I can see that eg. MS Word supports them so they basically should be implemented in KMemo as well. Only I don't know the timeframe for this, now I am very busy.
inserted: 2017-11-09 14:46:59   Reply...
From: см
I will think what to do when I get there.
inserted: 2017-10-09 11:15:09   Reply...
From: Davo
TK, I have made a start with writing that extra information I mentioned about KMemo I mentioned a few weeks ago. Please see -

And let me know if you don't like anything there ...

inserted: 2017-10-09 21:56:28   Reply...
From: tk
Very well done. At least you've done the basic search functionality (it would not work for tables and other nested containers). Keep moving here since I am actually very lazy at documenting and I still don't have enough time to do the big TODOs themselves (advanced search, undo/redo etc.). But it should be better soon.
inserted: 2017-10-10 08:18:17   Reply...
From: см
Well done.
I have added some info and made some fixes.
I would recommend: Do not use various names for the memo in the samples- either use KM or KMemo1, not both.

Also, similarly to what Tk mentioned, search functionality is far from working in the way you have written it.
  1. CrLf is considered by selection as a single character only, so if you want to find a string and select it, you will either have to replaces CrLf with a single character (Cr or LF) in a buffer string or will have to count occurences.
  2. Images are counted as 1 character.
  3. Special care shall be taken when creating tables.
  4. Anything always gets messed up.

The only reliable method for searhing I have found is:

//Searching backward won't be used
//Returns position at which a string is found
function CrawlSearchMemo (const SoughtString: string; var Memo: TKMemo; StartPos: integer=0; CaseSensitive: boolean=False): integer;
  SPos: Integer;
  SSLen: Integer;
  StepNext: byte=1;
  Found: boolean=False;
  mStartPos: integer;
  SSLen:= Length(SoughtString);
  if SSLen<1 then exit;
  if UTF8Pos(SoughtString,Memo.Text)=0 then exit; //Much faster than the process below
  if StartPos=0
    then mStartPos:=Memo.Blocks.RealSelStart+StepNext
    else mStartPos:=StartPos;
  for SPos:=mStartPos to UTF8Length(Memo.Text)- 1 do
    Found:= (StringCompare(SoughtString,Memo.Blocks.SelText,CaseSensitive)=0);
    if Found then
    end; //if Found
  end; //for SPos

The aforementined method is extremely slow, so I actually use hybrid searching (search approximately where the string is and then proceed with crawlsearch) which ai might post later.

Also, I would recommend not to use any string related function or procedure which does not start with UTF8... otherwise you are in a big trouble.
inserted: 2017-10-11 00:42:52   Reply...
From: Davo
And thanks for the correction of KMemo1.Lock.... You have highlighted the fact that I have, in fact used that in my app. Better fix that Davo !
inserted: 2017-10-11 00:36:12   Reply...
From: Davo
Thanks CM, I'm particularly interested in the UTF8 comments, something I will have to deal with soon in my real app. No experience there, I only speak English, here in Australia, thats all we do sadly.

Are you active on the Lazarus forum ? TK may not want us clogging up his help line with in depth technical discussions ....

My app does not use the search model I put on the page, as I need to search for (typically) 200 search terms on every change event, far too slow ! The model I put on the page is more about demonstrating the idea. Its important when presenting a new idea to someone to do so in as simple a way as possible. Otherwise, they get bogged down in (irrelevant to them) side issues. Perhaps I need to add a bit more saying my search is only about text, does say so at top of document but not as clear as it should ?

Thanks for picking up those typos and I agree about using KM v. KMemo1, its an artifact of me copying out of a several different units, the reader does not need to know that !

I still need to cover bullets and few other topics, I'd like to see contributions from other users, especially yourself ! The learning curve at the start is a bit steep, be great to help other users get into this excellent component set.
inserted: 2017-10-12 08:36:39   Reply...
From: см
I can be found in the Lazarus forum as cm630, but I am not much active there.
I suppose it would be a good idea to have a general thread about TKMemo ot TKControls.
There is nothing special in using UTF 8, just use:
  Utf8Length instead of Length
  Utf8Left instead of Left
  Utf8Right instead of Right
  Utf8Copy... insted of Mid
  UTFPos insted of Posx....
And it is good that a native English speaker could take for the wiki.

Are you sure (I mean have you tried) that „On Unix like systems, the position in KMemo1.Blocks.Text can be used directly as a TKMemoSelectionIndex.‟? I suppose that misusing a single character instead of CrLf happens in pure text files only, and I expect it not to happen in a specified format like RTF.

As far as my contribution to wiki is concerned- I will check my notes, but if I happen to find some spare time, the first thing to do will be working on adding support for highlighting in TKMemo.
inserted: 2017-10-13 01:43:05   Reply...
From: Davo
"Are you sure (I mean have you tried) that „On Unix like systems, the position in KMemo1.Blocks.Text can be used directly as a TKMemoSelectionIndex.‟?"

Yes, tested extensively. Sure ?, no in that that its an "undocumented" feature and could change without notice. My testing covered ONLY text content. TKMemoSelection index counts one char position for a new para (but interesting, shows its length() as 2). Same as #10. And Windows CR/LF is two char #13#10, so subtract 1 for every #13 you see. The counting #13 does no harm under Unix, there arn't any. But I ifdef it out anyway to save a bit of time.

However, I am concerned what happens if I start putting UTF8 char in there. And thats where I am on unfamiliar ground.

I have just sent my draft app out to the opensource community I'm with and we'll see some feedback I hope. If some of the auto changes to text crop up in the wrong position, then I'll know I have a problem. And it will be a big one!

Wow ! Did you say HIGHLIGHTING ??? That would be so cool. In my app, I have used red text instead of the yellow background our old app uses. And I hate it.
inserted: 2017-10-17 08:41:35   Reply...
From: см
Returning a single char as a NewLine in Linux seems prtty odd to me, but in the recent weeks I won't be able to try it. Maybe it is a bug, or maybe lazarus could be forced to work the same way under Windows.
Also one should bear in mind, that Apples also use a single charcter NL, but they do not use the same one as Linux (one uses CR and the other uses LF).
   There is no reason to be afraid of UTF8, TKMemo is using it internally.
   I *almost* had highlighting working, but I will need some assistance from TK, if he could spend the time. But first I will have to deal with bitbucket's revision system.
   Also, this thread is important: Last time I checked, changes were not implemented in Lazarus, so I still do not dare to use its native Replace routines.

inserted: 2017-10-21 05:22:47   Reply...
From: Davo
Hi CM, I am not sure what you find odd with Linux returning a one character newline. Thats standard Unix. Both Linux and OSX use LineFeed, #10. (The old Mac OS did #13 I think, too long ago).

I would not see any aspect of this as a bug, it works pretty much as I'd expect.

yes, agree with your concern with copying large strings, in my app I use a PChar, too old to trust these self sizing structures. And PChar is almost C .....

inserted: 2017-10-09 04:12:53   Reply...
From: Davo
TK, I hope you don't mind me asking, I'm not nagging, just need to know how to proceed.

I'm asking if you have plans to fix the KMemoParagraph.Number := pnuNone bug soon ? I have a rather clumsy partial workaround, only needed on Linux. Should I keep working on that or wait for your (much better) fix ?

I'm getting to the stage where I'd like to show what I have done to a particular open source community pretty soon. Its all made possible by your brilliant package.

Thanks, David
inserted: 2017-10-09 21:47:05   Reply...
From: tk
This bug should be fixed already, see I just hope my fix was better than yours:)
inserted: 2017-10-10 02:02:55   Reply...
From: Davo
Indeed ! If I'd clicked refresh on my browser, I'd have seen that !
Thanks indeed, it works perfectly. And far better than my approach of following the bullets down the page, and then canceling then one by one on the way back up !

inserted: 2017-10-08 11:37:59   Reply...
From: Davo
Kmemo - another aspect of the SelStart v. RealSelStart perhaps ?

If a user selects a bit of text and then presses 'Enter', what happens depends on the direction of the selection.

(Mouse) Right to Left - the text remains, is pushed down one line.
Left to Right - the text disappears, thats what I'd expect.

If you press a normal key it all works as expected, only an issue if you press Enter.

Same on Linux, Windows and Mac.

Any suggestions ?
inserted: 2017-10-09 22:04:02   Reply...
From: tk
I can confirm this. Eg. MS Word behaves the same for both directions - selected text is deleted first. So it is a bug IMO. Thanks for reporting - I will fix this later.
inserted: 2017-09-25 12:31:27   Reply...
From: yoni
Can KDBGrid be used with dynamic queries? (i.e. the columns are not predefined)

Currently when I tested it on lazarus 1.8rc4 the grid draws one empty column.

inserted: 2017-09-25 22:10:47   Reply...
From: tk
inserted: 2017-09-25 08:00:20   Reply...
From: Davo
Performance issues when adding to KMemo ?

My app reads in an XML file which I parse and poke into KMemo using functions like AddTextBlock(), AddParagraph() and property TextStyle.Font

I have determined that each of these calls take about 10mS. As the file I load needs about 500, 500 and such 350 calls, I'm seeing 14 to 15 seconds load time. And that sure won't do me any good at all I'm afraid.

Are you surprised at 10mS a call ?

I do stuff like -

    FT : TFont;
    TB: TKMemoTextBlock;
    setup FT
    TB := KM.Blocks.AddTextBlock(InStr);
    TB.TextStyle.Font := Ft;
    if something KM.Blocks.AddParagraph;

What do you think ?

inserted: 2017-09-25 22:09:51   Reply...
From: tk
Please read the KMemo manual carefully. Thanks.
inserted: 2017-09-26 01:27:21   Reply...
From: Davo
Sigh ...

Do you mean "...the KMemo update which is often a time consuming operation..update locking has been introduced.." ? I had read and applied that.

The manual does not say if Update Locking speeds things up or just prevents user interaction while its happening. My tests indicated the latter.

So, to make my question clearer, is there anything I can do to speed up these processes ?

Thanks TK.
inserted: 2017-09-26 10:13:32   Reply...
From: tk
The manual says:
"Please note each such operation will force the KMemo update which is often a time consuming operation, especially for large documents. For such cases, update locking has been introduced. "
I think the meaning is absolutely clear. Do what CM said.
inserted: 2017-09-26 09:23:02   Reply...
From: см
Add KM.Blocks.LockUpdate before your code and KM.Blocks.UNLockUpdate after your code (after populating the ENTIRE memo). Speed will be increased dramatically.
Do NOT use KM.LockUpdate (without .Blocks) because things will get messed up.
inserted: 2017-09-26 13:04:41   Reply...
From: Davo
OK, I have ordered a large serve of humble pie !
I went back and discovered that I had put my LockUpdate / UnLockUpdate pair around the wrong line of code!
Corrected that and went from 14sec to 83mS to load my test file. Wow !

(I have an object that loads the file, I create it, tell it the file name and then to load, then free it. I put my lock/unlock pair around the filename line, not the load one.)

Thanks folks, this is turning into something pretty good !
inserted: 2017-09-26 15:29:33   Reply...
From: см
Just an advice- if your memo starts to behave oddly- cannot select items, or messes selection or something like that- possibly you have missed to unlock the blocks.
inserted: 2017-09-27 00:46:26   Reply...
From: Davo
Yep, that would make sense.

I did note in my simple test rig that after (lock) importing (unlock) the text was invisible until I did a addparagraph without any locking.

Thought that pretty strange but quite repeatable. In my real app, that does not happen because I write other things to kmemo after importing any way.

Right now, I don't expect to need to apply locking at any stage other than the import process but time will tell.

Thanks CM.

inserted: 2017-09-23 14:46:29   Reply...
From: bitsolo

where is an help-file or how can i change the backgroundcolor of an specific cell in kgrid?
inserted: 2017-09-24 00:01:03   Reply...
From: tk
If you use non-virtual KGrid then use TKGridAttrTextCell as cell class:

KGrid1.CellClass := TKGridAttrTextCell;

Then simply use:

TKGridAttrTextCell(KGrid1.Cell[MyColumn, MyRow]).Brush.Style := MyColor;
inserted: 2017-09-23 13:20:14   Reply...
From: Davo
OK, this is a bit confronting. The values for KMemo1.SelStart and KMemo1.SelEnd can be reversed by wiping with the mouse in different directions.

Trivial to reproduce, put a KMemo on a form, a button to poke some text into it and another button to display SelStart and SelEnd when button clicked.

Wipe the mouse across text left to right, click display, then from right to left, click display again. Values are reveresed.

Wiping from right to left gives the correct result.

Bitbucket ver of KMemo, Lazarus 1.8rc4 and Linux.
inserted: 2017-09-23 23:51:56   Reply...
From: tk
Use RealSelStart/End instead.
inserted: 2017-09-22 22:03:14   Reply...
From: MVD
Got an error from the compiler for KControlsLaz in kgrids.pas

There is no method in an ancestor class to be overridden :
"DoAutoAdjustLayout(const TLayoutAdjustmentPolicy;const Double;const Double;const Boolean);"
in line (2945,15)
inserted: 2017-09-23 01:56:05   Reply...
From: Davo
MVD, just comment out the declaration and implementation of that function. Save the file and try again.
inserted: 2017-09-22 09:26:30   Reply...
From: Davo
I am having difficulties using Bullets or numbering in KMemo. While turning it on works fine, turning it off again causes a segv.

Doing a very simple model, for example, I do this -

if KMemo1.Blocks.Items[6].ClassNameIs('TKMemoParagraph') then begin
      TKMemoParagraph(KMemo1.Blocks.Items[6]).Numbering := pnuBullets;
      TKMemoParagraph(KMemo1.Blocks.Items[6]).Numbering := pnuNone;

in a KMemo that has some text blocks. I point to block 6 which I know is a TKMemoParagraph and as soon as we hit the pnuNone line, segv, line 8881 of kmemo.pas !

Note that the testDemo does not turn bullets off. And the Editor demo does a range of things with Listlevels that obscures what needs to be done. Do I have to look at ListLevels where just a simple bullet on/off is all I need ?

Bitbucket ver of KMemo, Lazarus 1.8rc4 on Linux.
inserted: 2017-09-23 23:51:01   Reply...
From: tk
This is a bug, thanks for reporting. Will fix that later.
inserted: 2017-09-20 13:36:11   Reply...
From: Davo
Using the Bitbucket version of KMemo. Made a hyperlink but not able to get an 'event' fired when the link is clicked.

It does not appear on the list of events for KMemo, should I look for it somewhere else ? Or do I need register it ?
inserted: 2017-09-23 23:50:32   Reply...
From: tk
TKmemoHyperlink block has its own Onclick event.
inserted: 2017-09-24 01:28:24   Reply...
From: Davo
"TKmemoHyperlink block has its own Onclick event."

Good, any hints on how to I use it ? It does not appear in the Lazarus GUI ?


TK, this is a great package, very functional but very hard to use because nothing is documented. Would you mind if I started documenting things like this as I find them ? Obviously all credit will remain with you, I'll make that plain. Focus on new users....

Perhaps in the Lazarus wiki ? I have been studying code, browsing through the prototype list, trying to guess what a function actually does. Very time consuming, you must loose a lot of potential users because they just give up.

inserted: 2017-09-24 11:40:22   Reply...
From: tk
There is already a wiki page for Lazarus users:

Of course you can add more info to it, eg. create subpage on KMemo, copy the KMemo manual to it and then you can start extending it.

Basic principles should stay, as described in the KMemo manual. But keep in mind that the control is not finished yet so some things may change in future.
inserted: 2017-09-24 10:53:59   Reply...
From: Davo
OK, solved first question. Searched older pages of this blog. In case someone else is watching -

    ... setup the Hyperlink ....
    Hyperlink.OnClick := @MyClickCommand;

Then, make the MyClickCommand procedure -

procedure TForm1.MyClickCommand(Sender: TObject);

That really is too easy ! (I was distracted by the WordMouseAction(..) thinking I had to use that. Sigh...)

Thanks TK.
inserted: 2017-09-24 11:33:28   Reply...
From: tk
Well done.

Just a note: KMemo is not finished by far and not fully documented yet!
It is also written in the control when you drop it to the form at design time.
If you want to use KMemo then you HAVE TO test everything yourself (create a sandbox project) and search on this forum as well!
Older comments
My account
Recently modified

KControls Component Suite

by: tk



by: tk



by: tk



by: tk


KGrid 1.3 released.

by: tk


Recently inserted


by: tk


Grouping of comments

by: tk



by: tk


My recent work on KMemo

by: tk


Update for RAD Studio XE2

by: tk