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

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

Notes

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 about cross-platform development in Delphi: I strongly disagree with the way Embarcadero took with the FMX library to allow cross-platform development, so FMX will never be supported. As Lazarus has become very good IDE, in many aspects better than Delphi, I recommend you try it if you need cross platform features.

Donations

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
downloads
Available for:Changes
kcontrols_1.7.zip1.75474Delphi 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.62648Delphi 6+,Lazarus 1.2.2+, C++Builder 2007+support for RAD Studio XE6, Columns property in TKDBGrid, bugfixes...
kcontrols_1.5.zip1.5349Delphi 6+,Lazarus 1.2.2+, C++Builder 2007+new components TKMemo, TKBitBtn, TKColorButton, some bugfixes...
kcontrols_1.4.zip1.4997Delphi 6+, Lazarus 0.9.29(SVN#21827)+, C++Builder 2007+support for RAD Studio XE3-XE5, new components etc.
kcontrols_1.3.zip1.32716Delphi 6+, Lazarus 0.9.29(SVN#21827)+, C++Builder 2007+support for RAD Studio XE2
kcontrols_1.2.zip1.23083Delphi 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.11089Delphi 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.01695Delphi 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: 2017-04-17 09:18:48   Reply...
From: CT
Hi,

Is it possible to do grouping in KDBgrid ?

Thanks
inserted: 2017-04-26 23:15:25   Reply...
From: tk
What is grouping?
inserted: 2017-04-05 15:37:53   Reply...
From: см
Hi,
I cannot find a way to disable text wrapping for a text block or a table cell.
   TKMemoTextBlock.WrapMode is read only;
   TKMemoTextBlock.WordBreakStyle has no option NoBreak;
   TKMemoTextBlock.WordBreaks is read only;
Could there be a way to disable wrapping?
inserted: 2017-04-07 14:27:18   Reply...
From: tk
This is possible only for a whole paragraph, with TKMemoParagraph.ParaStyle.WordWrap.
inserted: 2017-04-07 15:05:38   Reply...
From: см
I just found that
MyBlock.WordBreakStyle:=wbsFirstWordChar;
disables wrapping (sample below). But according your explanation, is this the expected behaviour?

procedure TForm1.Button4Click(Sender: TObject);
var
  MyTable: TKMemoTable;
  MyBlock: TKMemoTextBlock;
begin
   KMemo1.Blocks.Clear;
   MyTable:=KMemo1.Blocks.AddTable;
   MyTable.ColCount:=5;
   MyTable.RowCount:=5;
   MyTable.Cells[0,0].Blocks.AddTextBlock('0;0');
   MyTable.Cells[1,1].Blocks.AddTextBlock('1;1');
   MyBlock:=MyTable.Cells[2,2].Blocks.AddTextBlock('asdfljlkslkdflksjdflkasjkldsj kldfsklajdskladkljdksjldjklsdakjlkjdlfkasjldkdjfljkasdjkldaskjldkjlsdajkldsajkldsjk;ldsajkl;dsakjl;sadjkl;daskjl;daskjl;adsfjk;lreiotoietyitetiuoetuietieiptuoiupoteiupofljkjfskfgsdjjfksd;jkfldj;klfdxvcxvcn.vxcn.vc,.m');
   MyBlock.WordBreakStyle:=wbsFirstWordChar;
   MyBlock:=MyTable.Cells[2,2].Blocks.AddParagraph;
   MyTable.Cells[3,3].Blocks.AddTextBlock('3;3');
end;
inserted: 2017-04-07 16:10:13   Reply...
From: см
And this disables wrapping for a cell of a table:

if aMemoTable.Rows[Row].Cells[Column].Blocks.Count>0 then
  for BlockIndex:=0 to aMemoTable.Rows[Row].Cells[Column].Blocks.Count-1 do
   if aMemoTable.Rows[Row].Cells[Column].Blocks[BlockIndex] is TKMemoTextBlock
then TKMemoTextBlock(aMemoTable.Rows[Row].Cells[Column].Blocks[BlockIndex]).WordBreakStyle:=wbsFirstWordChar;
inserted: 2017-04-26 23:14:55   Reply...
From: tk
Actually wbsFirstWordChar has not been tested yet.
I am pretty sure it now equals 'wbsNoBreak' because under normal circumstances the condition CharInSetEx(S[1], [cTAB] + Wordbreaks), now present in TKMemoTextBlock.GetWordBreakable, always returns False.


inserted: 2017-04-04 13:39:12   Reply...
From: Ian
When we set EditorMode to False in TKGrid, if there is not text in the editor control then an exception is raised.

I have tracked the problem to GetControlText which is in KControls. Within this function is GetTextBuf. Before the line Value.GetTextBuf(...) I have added:
if Length(Result) > 0 then

This has stopped the exception.
inserted: 2017-04-04 21:21:40   Reply...
From: tk
Thanks, I will apply your patch in next commit.
inserted: 2017-04-05 11:47:34   Reply...
From: Ian
Glad I could contribute, even if in such a small way.

Thank you for such a great component.
inserted: 2017-03-30 16:47:55   Reply...
From: Sat1
Dobry den, existuje prosim nejaka moznost jak nastavit sirku sloupcu DBGridu v kodu? Klasicka moznost DBGrid1.Columns[i].Width neni.
Dale prosim o radu zda lze v sloupci zobrazit hodnoty v comboboxu, nebo listboxu.
Moc dekuji
inserted: 2017-03-31 14:18:11   Reply...
From: tk
Please speak English here so that others can read this thread.

1. In KDBGrid there is TKDBGrid.Columns[I].Extent (or classic TKDBGrid.ColWidths[I] instead of TDBGrid.Columns[i].Width.

2. You can show/edit cells in combobox or listbox with KDBGrid. You just have to create and use custom inplace editors for respective columns. Look at KGrid demo (event chain OnEditorCreate, OnEditorDataFromGrid, etc.) or maybe best at methods TKDBGrid.DefaultEditorCreate, TKDBGrid.DefaultEditorDataFromGrid etc.
inserted: 2017-03-27 14:37:15   Reply...
From: см
Hi,
In Lazarus, I am trying to resize an image and then add it into a TKMemo with the code below. For some reason only an empty rectangle is shown.
Could it be me doing something wrong or there is a problem in TKMemo?
When I add the downscaled image to Image1: TImage; it is displayed just fine.

procedure TForm1.Button1Click(Sender: TObject);
var
  ImagePicture: TPicture;
  bmp: TBitmap;
begin
  ImagePicture:= TPicture.Create;
  ImagePicture.LoadFromFile('c:\normal_image.png');

    bmp := TBitmap.Create;
    bmp.Width := Round(ImagePicture.Width /4);
    bmp.Height:= Round(ImagePicture.Height/4);
    bmp.Canvas.StretchDraw(Rect(0,0, Round(ImagePicture.Width /4), Round(ImagePicture.Width /4)), ImagePicture.Graphic);
    ImagePicture.Assign(bmp);
    bmp.SaveToFile ('c:\scaled_image.png'); //Downscaled image is stored to a file as expected

  Image1.Picture:= ImagePicture; //Downscaled image is displayed fine in Image1
  KMemo1.Blocks.Clear;
  KMemo1.Blocks.AddTextBlock ('Image top');
  KMemo1.Blocks.AddParagraph;
  KMemo1.Blocks.AddImageBlock(ImagePicture); //An empty rectangle is added in KMemo1
  KMemo1.Blocks.AddParagraph;
  KMemo1.Blocks.AddTextBlock ('Image bottom');
  bmp.Free;
  ImagePicture.free;
end;
inserted: 2017-03-31 14:05:11   Reply...
From: tk
TBitmap is not supported in KMemo. Convert the downscaled image to PNG and load it to KMemo.
inserted: 2017-04-04 16:34:48   Reply...
From: см
Thanks, I downscaled to PNG directly and it works.
inserted: 2017-03-25 10:09:03   Reply...
From: taazz
There is a small bug in the TKPageControl component in lazarus. A number of SigsegV exceptions are raise when ever a tabsheet is destroyed after it was placed inside a kpagecontrol. The problem comes form the TTabSheets class which is based on the TObjectlist which in turn has the OwnsObjects property set to true by default. Every a TKtabsheet is removed from the pagecontrol it is automatically destroyed and in most cases a second call free follows which raises the exceptions.
inserted: 2017-03-31 14:03:01   Reply...
From: tk
TKPagecontrol has not yet been fully finished and tested in Lazarus.
inserted: 2017-03-15 13:21:00   Reply...
From: см
Hi Tk,
I have some problems with
Memo.BorderStyle:=bsNone;
Something after calling it after resizing the memo the memo is not displayed at all.
I changed the code to
   if (Memo.BorderStyle<>bsNone) then Memo.BorderStyle:=bsNone;
and now prolems seem to be gone, but I assume that this check should be done internally.
inserted: 2017-03-20 10:15:33   Reply...
From: tk
Is it only Lazarus issue? Or happens in Delphi as well?
inserted: 2017-03-21 06:54:49   Reply...
From: см
I have observed it only in Lazarus, I cannot test in Delphi.
I will try to create a reproducing code, if you would consider it necessary?
inserted: 2017-03-21 07:55:02   Reply...
From: см
Below is the code, that demonstrates the issue. Just click on the titlebar to maximize the window. After uncommenting {if (ReportMemo.BorderStyle<> bsNone) then} behaviour seems fine.


unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, kdbgrids,
  kmemo;

type

  { TForm1 }

  TForm1 = class(TForm)
    ReportMemo: TKMemo;
    procedure FormResize(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormResize(Sender: TObject);
var
  NewWidth, NewHeight: integer;
begin
  NewWidth:= self.Width-10;
  NewHeight:=self.Height-30;
  ReportMemo.Left:=2;
  ReportMemo.Top:=26;
  ReportMemo.Width:=NewWidth;
  ReportMemo.Height:=NewHeight;

  {if (ReportMemo.BorderStyle<> bsNone) then} ReportMemo.BorderStyle:=bsNone;
  ReportMemo.ContentPadding.All:=0;
  ReportMemo.ReadOnly:=True;
end;

end.
inserted: 2017-03-21 08:10:07   Reply...
From: см
Sorry, I should heve written of „Just DOUBLE click on the titlebar‟ instead of „Just click...‟
inserted: 2017-03-21 20:10:53   Reply...
From: tk
This is a Lazarus/LCL bug and occurs even with normal TMemo. In Delphi XE this behaves just fine. Please report this problem to Lazarus bugtracker.
inserted: 2017-03-23 07:59:51   Reply...
From: см
Done: http://mantis.freepascal.org/view.php?id=31586
inserted: 2017-03-09 12:22:14   Reply...
From: см
Hi TK,
Executing Memo.Visible is very slow when content is huge.
Using .lockupdate and .unlockupdate makes things signifficantly faster.
Maybe they could be added in the .Visible routine?
inserted: 2017-03-20 10:14:45   Reply...
From: tk
I cannot see the difference but it is possible to add this.
inserted: 2017-03-05 16:25:33   Reply...
From: uvs
I try install on C++ Builder XE7 and have error:
"can't be installed because it was created with a different version of delphi or c++ builder"
Build is success.
inserted: 2017-03-06 09:09:28   Reply...
From: tk
And installation in Delphi XE7 works?
inserted: 2017-03-06 19:25:24   Reply...
From: uvs
I havn't Delphi. I try only C++ Builder.
inserted: 2017-03-07 08:21:57   Reply...
From: tk
Then I don't know what is the reason and you'll have to figure it out yourself. There is full source available, so it should work. I don't use /have C++ Builder at all now. I only tried in C++ Builder XE some years ago, there it worked so I assumed it would install in later versions as well.
inserted: 2017-03-02 08:33:25   Reply...
From: Deyan
Hello. I am testing TKMemo component on Lazarus IDE v1.6.2 , Ubuntu 16.04. I just put TKMemo, TKPrintSetupDialog, TKPrintPreviewDialog.
My questions are:
1. How to pre-setup the values of PrintSetupDialog, before to call it? Ex:I want margins left,right,top,bottom to be =0 by default
2. I put simple text in the memo Ex: Hello world. The print result is always with BLACK background (negative). Same test under Windows and Delphi7 is OK
inserted: 2017-03-02 10:28:31   Reply...
From: tk
Don't even try to print under GTK2 in Lazarus. There are lot of problems in that widgetset. Previewing works but printing not (at least to the extent I need for KControls). You can try QT, it should be better but I don't remember that exactly anymore. Or you can try to fix the problems in the GTK2 widgetset yourself.
inserted: 2017-02-23 22:02:01   Reply...
From: Josh
Hi
Having an issue changing font in tkgrid, using latest LAZ/FPC trunk and latest kcontrols from here.
I cannot change the font for the grid, if I change the grid font to something like Eurostile it does not alter visually, if I change the font for say a memo or stringgrid these change the accordingly.
I have tried setting the font in ide and in code, ie in form create kgrid1.font.name='Eurostile'; this has no effect either.

Ant ideas; or is this not supported and I have to change the font for each cell in OnDrawCell.
inserted: 2017-02-23 22:25:50   Reply...
From: Josh
I think I have figured it out. The parentfont property must be set to false to allow overriding of the Font Property; StringGrid Memo etc do not require this property to be set to false to allow font re-assignment. So did not think about about.
It occurred when I saved a project that I had changed the font to, and when I reopened it the font was set to default.
inserted: 2017-02-28 09:36:36   Reply...
From: tk
I've fixed it in the trunk. It works now both in KGrid and KMemo. Font size changes in KGrid at design time need reopening the form to update the row height.
inserted: 2017-02-14 19:22:24   Reply...
From: frank
TK,
I check the trunks on bitbucket... but there are so many changes since 1.7 that I have am not going to download each individual file.

Don't you have the latest build with all files??
I want to re-install the entire package with updated files.
inserted: 2017-02-14 21:56:38   Reply...
From: tk
You must pull to your local repository or download entire repository (link under Downloads section). You are not working with github or bitbucket?
inserted: 2017-02-13 11:04:12   Reply...
From: kosthala
I'm trying to install kcontrols in Delphi 2007 and i get error:
[Pascal Error] kbuttons.pas(144): E2147 Property 'ParentDoubleBuffered' does not exist in base class.

Can you help me?
inserted: 2017-02-13 16:53:30   Reply...
From: tk
Hmm, it seems that ParentDoubleBuffered has been added in Delphi 2009 first and not in 2007 as I assumed. In that case its declaration in TKCustomControl is wrong and it should be:
{$IF DEFINED(FPC) OR NOT DEFINED(COMPILER12_UP)}
...
    property ParentDoubleBuffered: Boolean read FParentDoubleBuffered write FParentDoubleBuffered default True;
{$IFEND}

I'll fix this on next occasion.

Unfortunately, for all newly added properties, the version of their addition to VCL is missing in Embarcadero documentation...
inserted: 2017-02-12 12:15:54   Reply...
From: array81
Does KMemo support header and footer?
inserted: 2017-02-12 16:22:11   Reply...
From: tk
If you mean editable header and footer that is also saved to RTF, like in Word, then this is not supported (and is far from being supported in near future), along with paging, sections etc., all are big TODOs.

Now it is only possible to add custom code to OnPrintPaint event, for preview/print. There custom header or footer might be added for each page. An example is shown in the KGrid demo.
inserted: 2017-02-11 13:39:30   Reply...
From: frank
Does KMemo support copy and paste of images? Because I can't seem to paste an image from clipboard into a block
inserted: 2017-02-11 20:36:32   Reply...
From: tk
It was not supported but I've added it just now. Copy&paste to Kmemo now works for RTF, plain text and images, copy&paste from Kmemo was not modified, is RTF and plain text only. Maybe here in future the first selected image could be inserted to clipboard as well (or if just one image block is selected).
inserted: 2017-02-10 17:01:28   Reply...
From: frank
KMemo... I have s test string 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.... when the width of the memo is made narrow... that long text string doesn't wrap, but goes off screen. Yet, I don't want horz scrollbar.
inserted: 2017-02-11 02:24:31   Reply...
From: frank
Also.. when it doesn't wrap the scrollbar doesn't show either
inserted: 2017-02-11 10:06:31   Reply...
From: см–
Did you try the latest release from bitbucket?
AFAIR a problem with the scrollbars was fixed a few weeks ago.
inserted: 2017-02-11 13:30:36   Reply...
From: frank
I downloaded the one from this site. What is the URL for bitbucket? There is no link on this site I can see.
inserted: 2017-02-11 13:33:13   Reply...
From: frank
found the link
inserted: 2017-02-10 11:23:46   Reply...
From: см
Hi,
I am trying to add a TKMemoTable.Assign property to assign tables, at leastin the extent that I need.
Merging cells seem to work, there is some problem with cell borders, for which I have a workaround, but I cannot make ColumnWidths works, which is a signifficant problem for me.
Any hint how to make ColumnWidths work will be appreciated.
It does not work even after the table is created, assigned and displayed.

Code is below:

procedure TKMemoTable.Assign(ASource: TKObject);
var
  Row: integer;
  Clm: integer;
  SourceTableCell: TKMemoTableCell;
  ColWidth: integer;
begin
  inherited;
  if ASource is TKMemoTable then
  begin
      LockUpdate;
      for Clm:= 0 to TKMemoTable(ASource).ColCount-1 do
      begin
        for Row:= 0 to TKMemoTable(ASource).RowCount-1 do
        begin
          SourceTableCell:=TKMemoTable(ASource).Cells[clm,row];
          Cells[clm,row].ColSpan:=SourceTableCell.ColSpan;
          Cells[clm,row].RowSpan:=SourceTableCell.RowSpan;

          //None of these are not working
          Cells[clm,row].BlockStyle.BorderWidths:=SourceTableCell.BlockStyle.BorderWidths;
          Cells[clm,row].BlockStyle.BorderWidth:=SourceTableCell.BlockStyle.BorderWidth;
          Cells[clm,row].BlockStyle.BorderColor:=SourceTableCell.BlockStyle.BorderColor;

          Cells[clm,row].RequiredBorderWidths.Left:=SourceTableCell.RequiredBorderWidths.Left;
          Cells[clm,row].RequiredBorderWidths.Right:=SourceTableCell.RequiredBorderWidths.Right;
          Cells[clm,row].RequiredBorderWidths.Top:=SourceTableCell.RequiredBorderWidths.Top;
          Cells[clm,row].RequiredBorderWidths.Bottom:=SourceTableCell.RequiredBorderWidths.Bottom;

          CellStyle.Assign(TKMemoTable(ASource).CellStyle);
  // ApplyDefaultCellStyle; //This is fine for my needs, but not in general
          //END These are not working

          Cells[clm,row].BlockStyle.Brush:=SourceTableCell.BlockStyle.Brush; //Copy background colour
        end; //for Row

        FColWidths.AddItem(0);
        ColWidth:=TKMemoTable(ASource).ColWidths[Clm];
        if (ColWidth>0) then ColWidths[clm]:= ColWidth;

       end; //for clm
    unLockUpdate;
  end; //if
end;
inserted: 2017-02-10 15:47:18   Reply...
From: tk
It has been already implemented, today I commited the changes. With those, at least your code below worked for me.
inserted: 2017-02-14 07:51:28   Reply...
From: см
Thanks!
I have tried it and so far it seems to works okay.
inserted: 2017-02-14 09:15:10   Reply...
From: см
As I used it more a problem ocurred:
When executing the code below the application crashes on line CellPos:= KMemo1.BlockRect(CellBlock); . Without using assignments, nothing crashes, positioning is on the expected row (although the column is 1 column wrong).

procedure TForm1.Button6Click(Sender: TObject);
 var
    Table: array of TKMemoTable;
    row, clm: integer;
    DispTable: TKMemoTable;
    MergeSpan: TKCellSpan;
    CellBlock: TKMemoBlock;
    CellPos: TRect;
begin
  KMemo1.Blocks.Clear;
  DispTable:= KMemo1.Blocks.AddTable;
  SetLength(table,1);
  Table[0]:= TKMemoTable.Create;
  Table[0].ColCount:=3;
  Table[0].rowCount:=15;
  Table[0].ColWidths[1]:=50;
    for row:=0 to Table[0].RowCount-1 do
      for clm:=0 to Table[0].colCount-1 do
      begin
        Table[0].Cells[clM,row].Blocks.AddTextBlock ('Table'+IntToStr(0)+'Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
        Table[0].Cells[clM,row].Blocks.AddParagraph;
      end;
    MergeSpan.ColSpan:=1;
    MergeSpan.RowSpan:=3;
    Table[0].CellSpan[1,2]:=MergeSpan;
    Table[0].CellStyle.BorderWidth:=1;
    Table[0].ApplyDefaultCellStyle;

    DispTable.Assign(table[0]);

    CellBlock:=Table[0].Cells[0,7].Blocks.BlockIndexToBlock(0);
    CellPos:= KMemo1.BlockRect(CellBlock);
    kmemo1.ExecuteCommand(ecGotoXY, @CellPos.TopLeft);
end;
inserted: 2017-02-16 21:24:57   Reply...
From: tk
When you call Assign a COPY of the table Table[0] is inserted to the memo. This is again one of the VCL/LCL basic principle. I hope here again you can see the bug you've made.

But I had bug in KMemo1.BlockRect as well - it should return zero point instead of exception, when the block was not found in the memo. I'll fix this on next occasion.
inserted: 2017-02-08 23:19:40   Reply...
From: Woj
Hello,
I can't set color for select bar in tkdbgrid.
I use "gdSelected in State" in OnDrawCell event but color don't change.
inserted: 2017-02-09 09:19:23   Reply...
From: Woj
I've found something. If I disable "goThemedCells" option then coloring in selection bar works, but I don't want to disable it. It looks like old school.
inserted: 2017-02-09 20:46:53   Reply...
From: tk
In goThemedCells mode KGrid uses Vista style selection (that looks fine in Vista and 7 but ugly in 10). If you want to disable it you either have to turn off goThemedCells or draw your cell on your own (not via CellPainter.DefaultDraw).
inserted: 2017-02-07 19:03:36   Reply...
From: RusMikle
Hi,

problem with 7_kontrols, compile on Mac (Virtual Box)
Images:
MacOS: http://www.superbasis.de/Tmp/mac_os.jpg
Lazarus: http://www.superbasis.de/Tmp/lazarus.jpg
Compile errors:
http://www.superbasis.de/Tmp/error1.jpg
http://www.superbasis.de/Tmp/error2.jpg

MfG RusMikle
inserted: 2017-02-09 20:49:03   Reply...
From: tk
You must use trunk version (from bitbucket).
inserted: 2017-02-01 09:18:36   Reply...
From: см
Hi,
I am trying to do the following: generate a number of tables and display one of them in a TKMemo, depending on my needs.
Since I had problems, I decided to try with something simpler, like text blocks.

1. I tried the following:

Sub....
var
  TxtBlock1: TKMemoTextBlock;
  TxtBlock2: TKMemoTextBlock;
begin
  TxtBlock1:=TKMemoTextBlock.Create;
  TxtBlock2:=TKMemoTextBlock.Create;
  TxtBlock1.Text:='Block 1';
  TxtBlock2.Text:='Block 2';
  TxtBlock2.TextStyle.Font.Bold:=True;
  KMemo1.Blocks.Clear;
  KMemo1.Blocks.AddAt(TxtBlock2);
  ShowMessage ('1');
  KMemo1.Blocks.AddAt(TxtBlock1);
  ShowMessage ('2');
  KMemo1.Blocks.AddAt(TxtBlock2);
end;

   Behaviour is: Block1 is shown correctly->Block1 is shown correctly (appended to Block1)->Block2 is appended to Block1, but it is erased from the begining of the line and the application crashes afterwards.

2. I tried the following:
Sub....
var
  TxtBlock1: TKMemoTextBlock;
  TxtBlock2: TKMemoTextBlock;
  DisplayBlock:TKMemoTextBlock;
begin
  DisplayBlock:= KMemo1.Blocks.AddTextBlock('');
  TxtBlock1:=TKMemoTextBlock.Create;
  TxtBlock2:=TKMemoTextBlock.Create;
  TxtBlock1.Text:='Block 1';
  TxtBlock2.Text:='Block 2';
  TxtBlock2.TextStyle.Font.Bold:=True;
  KMemo1.Blocks.Clear;
  DisplayBlock:=TxtBlock2;
  ShowMessage ('1');
  DisplayBlock:=TxtBlock1;
  ShowMessage ('2');
  DisplayBlock:=TxtBlock2;
end;

   Absolutely nothing gets displayed.

3. I tried the following:
Sub....
var
  TxtBlock1: TKMemoTextBlock;
  TxtBlock2: TKMemoTextBlock;
  DisplayBlock:TKMemoTextBlock;
begin
  DisplayBlock:= KMemo1.Blocks.AddTextBlock('');
  TxtBlock1:=TKMemoTextBlock.Create;
  TxtBlock2:=TKMemoTextBlock.Create;
  TxtBlock1.Text:='Block 1';
  TxtBlock2.Text:='Block 2';
  TxtBlock2.TextStyle.Font.Bold:=True;
  KMemo1.Blocks.Clear;
  DisplayBlock.Text:=TxtBlock2.Text;
  ShowMessage ('1');
  DisplayBlock.Text:=TxtBlock1.Text;
  ShowMessage ('2');
  DisplayBlock.Text:=TxtBlock2.Text;
end;

   Apllications crashed before displaying anything.

4. I tried the following:
Sub....
 var
  TxtBlock1: TKMemoTextBlock;
  TxtBlock2: TKMemoTextBlock;
  DisplayBlock:TKMemoTextBlock;
begin
  DisplayBlock:= KMemo1.Blocks.AddTextBlock('');
  TxtBlock1:=TKMemoTextBlock.Create;
  TxtBlock2:=TKMemoTextBlock.Create;
  TxtBlock1.Text:='Block 1';
  TxtBlock2.Text:='Block 2';
  TxtBlock2.TextStyle.Font.Bold:=True;
  KMemo1.Blocks.Clear;
  DisplayBlock.Assign(TxtBlock2);
  ShowMessage ('1');
  DisplayBlock.Assign(TxtBlock1);
  ShowMessage ('2');
  DisplayBlock.Assign(TxtBlock2);
end;

  Apllications crashed before displaying anything.

Since the Assign property was mentioned before, I ask in the Lazarus forum, and it occured that "by default it does nothing and generated an exception", unless it is modified.

Could there be another way to use a TKMemo element more than once?
inserted: 2017-02-02 01:17:56   Reply...
From: tk
Of course you can reuse TKMemo element more than once. You can add/remove/alternate blocks in the memo at will. But again you did a schoolgirl mistake in those examples (now less fragrant however!), its a pity I don't have the nice smileys here on my forum as they are on Lazarus forum ;D

Small help: Read chapter 3 of the KMemo manual carefully!
inserted: 2017-02-02 15:53:34   Reply...
From: см
I managed to copy a table by:
    if Assigned(DisplayTable) = False then
    begin
      ReportMemo.Blocks.Clear;
      DisplayTable:= ReportMemo.Blocks.AddTable;
    end;
    DisplayTable.Assign(ReportTables[ReportIndex]);
but it seems that using it this way cell merging gets lost.
I will check further on and feed back.
inserted: 2017-02-02 16:15:47   Reply...
From: см
Indeed, merging works in Button66, and does not work in button6.

procedure TForm1.Button66Click(Sender: TObject);
 var
    Table: array of TKMemoTable;
    row, clm: integer;
    DispTable: TKMemoTable;
    MergeSpan: TKCellSpan;
begin
  KMemo1.Blocks.Clear;

  SetLength(table,1);
  Table[0]:= KMemo1.Blocks.AddTable;
  Table[0].ColCount:=3;
  Table[0].rowCount:=15;
    for row:=0 to Table[0].RowCount-1 do
      for clm:=0 to Table[0].colCount-1 do
      begin
        Table[0].Cells[clM,row].Blocks.AddTextBlock ('Table'+IntToStr(0)+'Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
        Table[0].Cells[clM,row].Blocks.AddParagraph;
      end;
    Table[0].CellStyle.BorderWidth:=1;
    Table[0].ApplyDefaultCellStyle;
    MergeSpan.ColSpan:=1;
    MergeSpan.RowSpan:=3;
    Table[0].CellSpan[1,2]:=MergeSpan;
end;


procedure TForm1.Button6Click(Sender: TObject);
 var
    Table: array of TKMemoTable;
    row, clm: integer;
    DispTable: TKMemoTable;
    MergeSpan: TKCellSpan;
begin
  KMemo1.Blocks.Clear;
  DispTable:= KMemo1.Blocks.AddTable;
  SetLength(table,1);
  Table[0]:= TKMemoTable.Create;
  Table[0].ColCount:=3;
  Table[0].rowCount:=15;
    for row:=0 to Table[0].RowCount-1 do
      for clm:=0 to Table[0].colCount-1 do
      begin
        Table[0].Cells[clM,row].Blocks.AddTextBlock ('Table'+IntToStr(0)+'Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
        Table[0].Cells[clM,row].Blocks.AddParagraph;
      end;
    Table[0].CellStyle.BorderWidth:=1;
    Table[0].ApplyDefaultCellStyle;
    MergeSpan.ColSpan:=1;
    MergeSpan.RowSpan:=3;
    Table[0].CellSpan[1,2]:=MergeSpan;
    DispTable.Assign(table[0]);
end;
inserted: 2017-02-02 19:52:36   Reply...
From: tk
The reason is Assign is not yet implemented for TKMemoTable class.
inserted: 2017-01-24 12:41:59   Reply...
From: см
Hi,
Is there some method to search text in TKMemo and make it visible (shown it in the displayed area of the contents)?
Is there a way to highlight text?
I found no such example in the demos for TKMemo.
inserted: 2017-01-24 15:46:59   Reply...
From: tk
Nope. Is one of the main todo tasks. Has lower priority than Undo/Redo and table tools.
inserted: 2017-01-24 16:03:03   Reply...
From: см
And is it possible to make a cell of a table visible?
inserted: 2017-01-24 19:00:31   Reply...
From: tk
Cells in KMemo tables are always visible so you mean highlight it? This is of course possible. You can for example change its background with Cell.BlockStyle.Brush. Only now you have to search for the cell (or text in the cell) using your own code.
inserted: 2017-01-25 07:27:48   Reply...
From: см
I mean:
If I have a table with multiple rows, not all of them are visible in the screen, so I need to scroll to the desired cell.
In the code below ParentTable.Cells[1,21].top always returns 0, while I expected it to return the top of the cell, related to the parent TKMemo.
Also, I do not know how to pass XY to KMemo1.ExecuteCommand (ecGotoXY).

procedure TForm1.Button4Click(Sender: TObject);
var
  ParentTable: TKMemoTable;
  row, clm: integer;
  celltop: integer;
  cellleft: integer;
begin
  ParentTable:=KMemo1.Blocks.AddTable;
  ParentTable.ColCount:=3;
  ParentTable.rowCount:=150;
  for row:=0 to ParentTable.RowCount-1 do
       for clm:=0 to ParentTable.colCount-1 do
             ParentTable.Cells[clM,row].Blocks.AddTextBlock ('Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
    ParentTable.CellStyle.BorderWidth:=1;
  ParentTable.ApplyDefaultCellStyle;

  cellleft:= ParentTable.Cells[2,1].Left;
  celltop:= ParentTable.Cells[1,21].top;
  TableLoaded:=True;
 // KMemo1.ExecuteCommand (ecGotoXY) ;
end;
inserted: 2017-01-25 15:20:30   Reply...
From: tk
I see. Actually there was no suitable method to get bounding rectangle for given block, in client coordinates of TKMemo.

I added new TKCustomMemo.BlockRect method in the trunk.

Usage (is probably what you want):

procedure TMainForm.Test;
var
  YourBlock: TKMemoBlock;
  R: TRect;
begin
  YourBlock := ...;
  R := KMemo1.BlockRect(YourBlock);
  // to just scroll:
  KMemo1.ClampInView(@R.TopLeft, True);
  // or to scroll and move the caret:
  KMemo1.ExecuteCommand(ecGotoXY, @R.TopLeft);
end;
inserted: 2017-01-26 07:33:16   Reply...
From: см
Hi,
Thanks for the new routine!

I order to make a row[50] of a table visible I did:
  YourBlock:= ParentTable.Cells[1,50].Blocks.BlockIndexToBlock(0);
  r:= KMemo1.BlockRect(YourBlock);

  KMemo1.ExecuteCommand(ecGotoXY, @R.TopLeft);
      or
  KMemo1.ClampInView(@R.TopLeft, True);

So, KMemo1.ExecuteCommand(ecGotoXY, @R.TopLeft); scrows until the desired row is in the bottom of the table (as desired),
but KMemo1.ClampInView(@R.TopLeft, True); does nothing.

Since the first solution works, I guess there is something wrong in ClampInView?
(as always, tested on Lazarus).
To make reproduction easier, the entires source is below:

procedure TForm1.Button4Click(Sender: TObject);
var
  ParentTable: TKMemoTable;
  row, clm: integer;
  celltop: integer;
  cellleft: integer;
   R: TRect;
   ownblock: TKMemoBlock;
begin
  ParentTable:=KMemo1.Blocks.AddTable;
  ParentTable.ColCount:=3;
  ParentTable.rowCount:=150;
  for row:=0 to ParentTable.RowCount-1 do
       for clm:=0 to ParentTable.colCount-1 do
             ParentTable.Cells[clM,row].Blocks.AddTextBlock ('Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
    ParentTable.CellStyle.BorderWidth:=1;
  ParentTable.ApplyDefaultCellStyle;

  ownblock:= ParentTable.Cells[1,50].Blocks.BlockIndexToBlock(0);
  r:= KMemo1.BlockRect(ownblock);

// KMemo1.ExecuteCommand(ecGotoXY, @R.TopLeft);

 // KMemo1.ClampInView(@R.TopLeft, True);
end;
inserted: 2017-01-26 10:41:06   Reply...
From: tk
Indeed there was problem in ClampInView in certain situations. This should be fixed now.
inserted: 2017-01-27 11:44:11   Reply...
From: см
Now ClampInView seems to work for me too.

But I noticed the following:
If I click on the tkmemo *before* executing the entire aforementioned snippet, the cursor is blinking.
After I execute the snippet with KMemo1.ExecuteCommand(ecGotoXY, @R.TopLeft); the cursor is not displayed (blinking). It gets displayed, after I click a button (i.e. LeftArrow).
I wonder if this is the expected behaviour?

I have also tried adding KMemo1.ExecuteCommand (ecLeft); in the end of the snippet, but the cursor is still not displayed.
inserted: 2017-01-27 15:30:36   Reply...
From: tk
Caret is not visible if memo is not focused. If you click on a button it steals input focus from the memo. To return focus to the memo either call KMemo1.SetFocus in the click handler or (shift+)tab through other controls until the focus again reaches the memo. You can also click on memo scrollbar - this returns focus to the memo as well.
inserted: 2017-01-30 07:16:14   Reply...
From: см
Precisely!
When trying it I noticed something else:
   1. If you execute the code below the table will be filled with „LineXColumnY‟.
If you click in some of the cells and you start moving the cursor with the left arrow key you will notice that the cursor moves to the next column 1 character earlier than it should.
For example if you click on „Line17Column0‟ and start pressing the right arrow, the cursor will move to the next column after it have reached the postion between „Line17Column‟ and „0‟. IMHO it should go after the „0‟, and just after that- move to the next column.
Behaviour is similar when left arrow is used.

procedure TForm1.Button4Click(Sender: TObject);
var
  ParentTable: TKMemoTable;
  row, clm: integer;
begin
  ParentTable:=KMemo1.Blocks.AddTable;
  ParentTable.ColCount:=3;
  ParentTable.rowCount:=150;
  for row:=0 to ParentTable.RowCount-1 do
       for clm:=0 to ParentTable.colCount-1 do
             ParentTable.Cells[clM,row].Blocks.AddTextBlock ('Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
    ParentTable.CellStyle.BorderWidth:=1;
  ParentTable.ApplyDefaultCellStyle;
end;
inserted: 2017-01-30 10:01:29   Reply...
From: tk
This is correct behavior. To step beyond "0" you must add paragraph after the cell text:

ParentTable.Cells[clM,row].Blocks.AddParagraph;
inserted: 2017-01-31 08:15:03   Reply...
From: см
Thanks, I will take care for adding paragraphs.
inserted: 2017-01-31 08:27:15   Reply...
From: см
Hi,
I just tried the code below, but behaviour is still the same.

procedure TForm1.Button6Click(Sender: TObject);
 var
    Table: array of TKMemoTable;
    i: integer;
    row, clm: integer;
begin
  SetLength(table,2);
  for i:=0 to 1 do
  begin
    Table[i]:=TKMemoTable.Create;
    Table[i].ColCount:=3;
    Table[i].rowCount:=150;
    for row:=0 to Table[i].RowCount-1 do
         for clm:=0 to Table[i].colCount-1 do
               Table[i].Cells[clM,row].Blocks.AddTextBlock ('Table'+IntToStr(i)+'Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
               Table[i].Cells[clM,row].Blocks.AddParagraph; //!!!
      Table[i].CellStyle.BorderWidth:=1;
    Table[i].ApplyDefaultCellStyle;
  end; //for i
  KMemo1.Blocks.Clear;
  KMemo1.Blocks.AddAt(Table[0]);
end;
inserted: 2017-01-31 10:13:17   Reply...
From: tk
Just try to figure out yourself what you did wrong. Its the very Pascal basics, I'll never answer such questions here.
inserted: 2017-01-31 11:43:31   Reply...
From: см
Sorry... begin ... end...
Works fine.
inserted: 2017-01-19 12:25:15   Reply...
From: см
Hi,
I am trying to create a hypelink containg an image.
While doing it I got to troubles with LoadFromRTFStream.
The coded from snippet 1 works fine, but the one from snippet 2 is not.
Is it me who is doing something wrong or is there problem in the implementation of LoadFromRTFStream?


//Snippet 1
procedure TForm1.cmdAddImgClick(Sender: TObject);
var
  ImageMemo: TKMemo;
begin
  ImageMemo := TKMemo.Create(Self);
  ImageMemo.Blocks.Clear;
  ImageMemo.Blocks.AddImageBlock('c:\tempimg.jpg');
  ImageMemo.SaveToRTF ('c:\tempimg.rtf');

  KMemo1.Blocks.Clear;
  KMemo1.LoadFromFile ('c:\tempimg.rtf');
end;

//Snippet 2
procedure TForm1.cmdAddImg1Click(Sender: TObject);
var
  ImageMemo: TKMemo;
  ImageStream: tstream;
begin
  ImageMemo := TKMemo.Create(Self);
  ImageStream := TStringStream.Create('');
  ImageMemo.Blocks.Clear;
  ImageMemo.Blocks.AddImageBlock('c:\tempimg.jpg');
  ImageMemo.SaveToRTFStream (ImageStream);

  KMemo1.Blocks.Clear;
  KMemo1.blocks.LoadFromRTFStream (ImageStream);
  ImageStream.Free;
end;
inserted: 2017-01-19 16:44:25   Reply...
From: tk
Put ImageStream.Seek(0, soFromBeginning); before KMemo1.blocks.LoadFromRTFStream.

But you won't be able to save the image as hyperlink to rtf stream because it is not yet supported! Modifications are required in units kmemo as well as kmemortf.

inserted: 2017-01-20 07:57:28   Reply...
From: см
Děkujem,
The solution with ImageStream.Seek(0, soFromBeginning);
works.
I realized, that I actually do not need hyperlinked images, since I need to display the contents of the image in another place.

So I did:
1.
procedure TForm1.KMemo1BlockClick(Sender: TObject; ABlock: TKMemoBlock; var Result: Boolean);
begin
  if ABlock is TKMemoImageBlock then
     begin
        KMemo2.Blocks.Clear;
        KMemo2.Blocks.AddAt (ABlock);
     end;
end;

It ocurred that the KMemo1BlockClick does not get fired when an image is clicked. It seems like a bug to me?


2. I decided to try if copying a block to another memo will work. So I did:
procedure TForm1.KMemo1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  myblock: TKMemoImageBlock;
begin
  if KMemo1.BlockAt(point(x,y)) is TKMemoImageBlock then
   begin
       myblock:=TKMemoImageBlock(KMemo1.BlockAt(point(x,y)));
       KMemo2.Blocks.Clear;
       KMemo2.Blocks.AddAt(myblock);
       myblock.ExplicitWidth:= 500;
   end;
end;

When I did a mouse down:
  1. The event fired
  2. The image was displayed in the other TKMemo2
  3. The image in TKmemo2 was selected just like in TKMemo1.
  4. Images in both blocks got resized. Obviously the block is passed as a variable.
     So here comes the second issue: How to copy the block, instead of referencing him? Maybe this is a general FPC question, I could ask in the Lazarus forum.
  5. When I clicked on the image in TKMemo1 the application threw an exception (while the KMemo1MouseDown procedure was executed).
     I guess there is some bug here or there is somethig which is not fully implemented?
 
I also wonder if there is way to prevent images from being selected? I tried myblock.Select(0,0,false); to diselect it, but in vain.
inserted: 2017-01-21 15:57:04   Reply...
From: tk
1. Is true, images don't fire OnBlockClick - this feature is not implemented yet. There was conflict with selecting/dragging the images which must be resolved.

2. Ough this is a very wrong way! You must create a new TKMemo...Block, assign the properties using Assign method, then insert it to another Kmemo! Just like you would have to do it with any other similar object list member in Object Pascal!

inserted: 2017-01-23 08:35:24   Reply...
From: см
Thanks, I googled „Assign‟, but it told me nothing else but „assign with :=‟.
I did

procedure TForm1.KMemo1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  SourceBlock: TKMemoImageBlock;
  TargetBlock: TKMemoImageBlock;
begin
  if KMemo1.BlockAt(point(x,y)) is TKMemoImageBlock then
   begin
// KMemo2.LockUpdate;
      SourceBlock:= TKMemoImageBlock(KMemo1.BlockAt(point(x,y)));
      KMemo2.Blocks.Clear;
      TargetBlock:= TKMemoImageBlock.Create;
      TargetBlock.Image:= SourceBlock.Image;
      KMemo2.Blocks.AddAt(TargetBlock);
      targetblock.ExplicitWidth:= 200;
      targetblock.ExplicitHeight:= 200;
// KMemo2.unLockUpdate;
  end;
end;

but this method is extremely slow (188 ms, while the other method took 16 ms only).
Using KMemo2.LockUpdate; slowed performance even much more.

I tried to use TargetBlock.Image.Assign (SourceBlock.Image); and SourceBlock.Image.Assign (TargetBlock.Image); instead of TargetBlock.Image:= SourceBlock.Image; but in both cases the app crashes.
I also tried TargetBlock.Assign(SourceBlock);. In this case behaviour is okay, but performance is the same (188 ms).

Probably TargetBlock.Image:= SourceBlock.Image; does some convertions like Bmp->Pdf->Bmp?
Could there be a faster way?
inserted: 2017-01-23 11:57:55   Reply...
From: tk
I am afraid you cannot speed this up. The image is always entirely copied (compressed to stream and decompressed) and does not use the default reference counted mechanism. It was introduced in r215 because of DPI dependent image scaling. Originally there was Image.Assign(TKMemoImageBlock(ASource).Image) but that did not work well in some cases, apparently due to bugs in LCL in some widgetsets.
It might be revisited later but now this will stay.

To (maybe!) speed this up you would need to copy the image directly to paint it somewhere else than in a second KMemo, eg. in a TImage component:

procedure TMainForm.Memo1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Block: TKMemoBlock;
  Pict: TPicture;
begin
  Block := KMemo1.BlockAt(Point(X, Y));
  if Block is TKMemoImageBlock then
  begin
    Pict := TPicture.Create;
    try
      Pict.Assign(TKMemoImageBlock(Block).Image);
      // do something with the image, eg.
      Image1.Picture := Pict;
    finally
      Pict.Free;
    end;
  end;
end;
inserted: 2017-01-23 13:13:33   Reply...
From: см
Podivuhodný! Execution took 0 ms.
I was ecpecting this to be the slower way, but obviously I was infinitely wrong.
inserted: 2017-01-23 13:57:15   Reply...
From: tk
Glad that it works for you now!

Please note I also made some modifications in the trunk. The OnBlockClick and OnDblBlockClick should now fire even for image blocks.
And I forgot to include relative positioned images into the BlockAt calculation...
inserted: 2017-01-24 08:16:03   Reply...
From: см
I downloaded the latest update.
I found the following issues:
OnBlockClick is fired only the first time a TKMemoImageBlock is clicked.
On the second click it is not fired.
If I click on another kind of block (i.e. TKMemoText) and then I click on a TKMemoImageBlock (the same image or another image in another block) the event is fired.
Also, when the event is fired
    if Block is TKMemoImageBlock then...
is not executed. For some reason the block is considered for sth. else.
I will try to create a standalone example later.
inserted: 2017-01-24 08:36:15   Reply...
From: см
I have made a snippet. In OnBlockClick does not fire at all when an image is clicked.

procedure TForm1.Button1Click(Sender: TObject);
begin
  KMemo1.Blocks.Clear;
  KMemo1.Blocks.AddTextBlock('Some text before') ;
  KMemo1.blocks.AddImageBlock ('c:\tempimg.jpg');
  KMemo1.Blocks.AddTextBlock('Some text after') ;
end;

procedure TForm1.KMemo1BlockClick(Sender: TObject; ABlock: TKMemoBlock; var Result: Boolean);
begin
    if ABlock is TKMemoImageBlock then
    begin
        ShowMessage ('aaa');
    end;
end;
inserted: 2017-01-24 10:11:36   Reply...
From: tk
You probably used a breakpoint in OnBlockClick?
Only then I could reproduce this issue and only in Lazarus (Delphi clearly notifies the control about a mouse up which was made in the IDE upon entering the breakpoint when a mouse button was down, Lazarus does not).

For image blocks OnBlockClick fires while in TKCustomMemo.MouseDown (and not in MouseUp like is the default way for other blocks).

But as the image dragging/resizing newly needs some movement with the mouse to start, then actually even for images the OnBlockClick event can now be fired in the default way (=while in MouseUp).

I've deleted corresponding assignments in the trunk.
inserted: 2017-01-24 10:50:44   Reply...
From: см
„You probably used a breakpoint in OnBlockClick? ‟
First I noticed sth. was wrong, after that I added a breakpoint.

It seems to work fine with the latest update!
inserted: 2017-01-18 17:02:10   Reply...
From: RusMikle
Hi!
Problem misalignment in TKGrid by halCenter, valCenter and Font.Orientation:=900:

    KGrid1.CellSpan[0, nT] := MakeCellSpan(1, 10);
    KGrid1Cells[0, nT] := '0123456789';

    with TKGridAttrTextCell(KGrid1.Cell[0, nT]) do
    begin
     Font.Assign(KGrid1.Font);
     Font.Orientation:=900;
     Font.Style := [fsBold];
     VAlign := valCenter;
     HAlign := halCenter;
.........
See result:
http://www.superbasis.de/2017_01_18_16_39_03_.jpg

(Lazarus 1.7, Windows 10, 7 kcontrols 1.7)
inserted: 2017-01-18 17:29:32   Reply...
From: tk
Font orientation other than default is not supported! You have to paint your cell in OnDrawCell.
inserted: 2017-01-16 17:10:12   Reply...
From: см
Hi,
I am trying to do some manipulation on a hyprlink when I click on it (in TKMemo).
I tried to add an OnMouseMove event in kmemo.pas but it just won't fire.
Probably there is some other way to achieve it?
OnBlockClick won't do, because it handles only left mouse button.
inserted: 2017-01-16 17:25:10   Reply...
From: см
Actually I need to handle both cases: when the mouse is over a hyperlink and when a hyperlink is clicked.
Maybe the most forward method would be to add a variable, which would store the Hyperlink when the TKMemoHyperlink.WordMouseAction event is triggered, but I still see some possible problems there.
inserted: 2017-01-17 11:44:57   Reply...
From: tk
Well this would require OnBlockMouseDown, OnBlockMouseMove and maybe also OnBlockMouseUp. I'll see what can be done.
inserted: 2017-01-17 12:12:13   Reply...
From: см
Or maybe if there is a function to return the selected block at given coordinates (X and Y) of the TKMemo? This way general TKMemo events could be used
... OnKMemo1MouseMove/Up/Down... GetBlockAtXY(X_from_mouse_move,X_from_mouse_move)... ?
inserted: 2017-01-17 15:54:35   Reply...
From: tk
Or in case of the table, a combination of PointToBlocks and PointToBlock?

PointToBlocks should give the innermost Blocks (here Cell.Blocks)
and PointToBlock then the block (hyperlink) at given position.

This would need some playing though as there is not yet a high level method directly implemented in the TKCustomMemo class...
inserted: 2017-01-17 15:49:35   Reply...
From: tk
Have you tried TKMemoBlocks.PointToBlock?
inserted: 2017-01-17 17:32:36   Reply...
From: см
So far I have tried the code below, but none of the
    if .... is TKMemoTextBlock then
cases got fulfilled.


procedure TForm1.Button4Click(Sender: TObject);
var
  ParentTable: TKMemoTable;
  imgblock: TKMemoImageBlock;
  debprn: integer;
  row, clm: integer;
  celltop: integer;
begin
  ParentTable:=KMemo1.Blocks.AddTable;
  ParentTable.ColCount:=3;
  ParentTable.rowCount:=150;
  for row:=0 to ParentTable.RowCount-1 do
       for clm:=0 to ParentTable.colCount-1 do
             ParentTable.Cells[clM,row].Blocks.AddTextBlock ('Line'+IntToStr(row) +'Column'+ IntToStr(clm)) ;
    ParentTable.CellStyle.BorderWidth:=1;
  ParentTable.ApplyDefaultCellStyle;

  debprn:= ParentTable.Cells[2,1].Left;
  celltop:= ParentTable.Cells[1,21].top;
    debprn:= ParentTable.Cells[1,20].Height;
        debprn:= ParentTable.Cells[1,20].Width;
    TableLoaded:=True;
end;

procedure TForm1.KMemo1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  var
  mypoint:TPoint;
  myblock: TKMemoBlock;
  myblocktext: String;
begin
  if TableLoaded = True then
   begin
   mypoint.x:= x;
   mypoint.y:= y;
   myblock:= KMemo1.Blocks.PointToBlock(mypoint);
   if myblock is TKMemoTextBlock then
    begin
      label1.Caption:=myblock.Text;
    end;
   if TKMemoTextBlock(myblock.Parent) is TKMemoTextBlock then
    begin
       label1.Caption:=myblock.Text;
    end;
    if TKMemoTextBlock(TKMemoTextBlock(myblock.Parent).Parent) is TKMemoTextBlock then
    begin
       label1.Caption:=myblock.Text;
    end;
  end;
end;
inserted: 2017-01-18 09:49:43   Reply...
From: tk
Again it was far more playing than I expected.
Use the new TKMemo.BlockAt method.
It returns the innermost block at given position.
It works even for relative and absolute positioned containers and their innermost blocks.

procedure TMainForm.Memo1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Block: TKMemoBlock;
begin
  Block := KMemo1.BlockAt(Point(X, Y));
  if Block is TKMemoTextBlock then
    Label1.Caption:= TKMemoTextBlock(Block).Text;
end;
inserted: 2017-01-19 11:50:45   Reply...
From: см
Thanks, I trying and it seems to work just fine!
inserted: 2017-01-19 11:52:10   Reply...
From: см
... but I wonder if a name like BlockAt wont be confusing?
Maybe GetBlockAt is better?
inserted: 2017-01-19 16:39:21   Reply...
From: tk
I don't like Get/Set prefixes for other methods than property getters and setters. Even somewhere I've read an article about it but don't know where anymore.
inserted: 2017-01-11 10:40:12   Reply...
From: СМ
Hi Tk,
A few days ago I mentioned that I had no problems with nested tables but now it occurs, that content of nested tables overlap neighbouring cells (on the right).
Actually this is the result of the parent table NOT self resizing- it stays with the size of the KMemo in which it is located.
I have explicitly set MyKmemo.ScrollBars:=ssBoth; and ParentTable.FixedWidth:=false; but it still does not get resized out of the KMemo. Horizontal scrollbar is not shown, only a vertical one.

I tried to reproduce standalone with a simpler case, but the problem is not occuring there.
Do you have an idea what might be the reason for this and how to get around it?
Maybe I could send or upload some additional info somewhere?
inserted: 2017-01-11 13:12:42   Reply...
From: СМ
I have sucessfully reproduced it in a standalone test.
There is something wrong in merged cells. The source which demontrates the issue follows below:

uses
  ...kfunctions...

procedure MergeCells(var aTable: TKMemoTable; aLeft: integer; aTop: integer; aRight: integer; aBottom: integer);
var
  MergeSpan: TKCellSpan;
begin
  MergeSpan.ColSpan:=aRight-aLeft+1;
  MergeSpan.RowSpan:=aBottom-aTop+1;
  aTable.CellSpan[aleft,atop]:=MergeSpan;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   row, col: integer;
   aMemoTable: TKMemoTable;
   ParentTable: TKMemoTable;
   imgblock: TKMemoImageBlock;
begin
  ParentTable:=KMemo1.Blocks.AddTable;
  ParentTable.ColCount:=2;
  ParentTable.rowCount:=4;
  MergeCells(ParentTable,0,1,1,1);
  ParentTable.Cells[0,0].Blocks.AddTextBlock ('Row1Column1') ;
  ParentTable.Cells[0,1].Blocks.AddTextBlock ('Row3Column3') ;
  ParentTable.Cells[1,0].Blocks.AddTextBlock ('Row1Column3') ;
  ParentTable.Cells[1,1].Blocks.AddTextBlock ('Row1Column3') ;
  ParentTable.Cells[0,2].Blocks.AddTextBlock ('Row1Column1') ;
  ParentTable.Cells[0,2].Blocks.AddTextBlock ('Row3Column3') ;
  ParentTable.Cells[1,3].Blocks.AddTextBlock ('Row1Column3') ;
  ParentTable.Cells[1,3].Blocks.AddTextBlock ('Row1Column3') ;
  ParentTable.CellStyle.BorderWidth:=1;
  ParentTable.ApplyDefaultCellStyle;

  aMemoTable:=ParentTable.Cells[0,1].Blocks.AddTable;
  aMemoTable.ColCount:=20;
  aMemoTable.rowCount:=5;
  aMemoTable.ColWidths[2]:=20;
  for row:=0 to trunc((aMemoTable.rowCount -1)/2)-1 do
     for col:=0 to aMemoTable.ColCount -1 do
        begin
           aMemoTable.Cells[col,row*2].Blocks.AddTextBlock ('Row' + IntToStr(row) + 'Column1'+IntToStr(col)) ;
           aMemoTable.Cells[col,row*2+1].Blocks.AddTextBlock ('SomeContent') ;
        end;
  aMemoTable.CellStyle.BorderColor:=clBlue;
  aMemoTable.CellStyle.BorderWidth:=1;
  aMemoTable.ApplyDefaultCellStyle;

 //ImgBlock:= aMemoTable.Cells[col,row].Blocks.AddImageBlock('c:\tempimg.jpg');
end;
inserted: 2017-01-11 19:36:05   Reply...
From: tk
Thanks for the sample (had to adapt it a bit, again it used unsupported empty cells). There was a bug indeed - merged cells were measured incorrectly. The problem occured not only for nested tables but for long words as well. I've fixed some other minor problem with table layout calculation.
inserted: 2017-01-12 08:16:22   Reply...
From: СМ
Hi, I have not tested all the previous cases yet, but since now I see the following problem: The rightmost column is cropped from the left, but no horizontal scroll bar is shown.
This happens in tables in which there is no long words so there is no reason to make the columns so wide and it seems like a regression to me.
In cases where tables is wider and horizontal scrollbars are shown, still the rightmost column is cropped.
Could this be due to to having spacing on the left side of the table. I also wonder, is there a way to remove this spacing between the tables and the borders of the memo?
inserted: 2017-01-12 09:28:42   Reply...
From: tk
I cannot reproduce the cropping with the above sample and any of my other test tables.

Column widths for columns participating in a merged cell are now set equally to merged_cell_width/number_of_merged_column. That maybe causes your non-merged cells to be wider than they should be. To fix this, more 'clever' algorithm would be needed but I have no time for this now. So either use simpler tables or provide a patch to me.
inserted: 2017-01-12 09:52:45   Reply...
From: СМ
I have done some other testing, I have reproduced it without merging and withiut nesting tables, with the code below. It uses an image with dimensions W1300; h1712, but in some cases I see the problem without an image.
In the example the rightmost characters are not visible (actually say 10% of the last but one character is visible).
Could this be a Lazarus problem only, not happening in Delphi?
I have used the default font.
I could upload the image somewhere if you consider it useful.

procedure TForm1.Button2Click(Sender: TObject);
var
  ParentTable: TKMemoTable;
  imgblock: TKMemoImageBlock;
begin
  ParentTable:=KMemo1.Blocks.AddTable;
  ParentTable.ColCount:=2;
  ParentTable.rowCount:=3;
  ParentTable.Cells[0,0].Blocks.AddTextBlock ('Line0Column0') ;
  ParentTable.Cells[0,1].Blocks.AddTextBlock ('Line1Column0') ;
  ParentTable.Cells[0,2].Blocks.AddTextBlock ('Line2Column0') ;
  ParentTable.Cells[1,0].Blocks.AddTextBlock ('Line0Column1') ;
  ParentTable.Cells[1,1].Blocks.AddTextBlock ('Line1Column1') ;
  ParentTable.Cells[1,2].Blocks.AddTextBlock ('Line2Column1') ;
  ParentTable.CellStyle.BorderWidth:=1;
  ParentTable.ApplyDefaultCellStyle;
  ImgBlock:= ParentTable.Cells[0,1].Blocks.AddImageBlock('c:\tempimg.jpg');
end;
inserted: 2017-01-12 11:13:54   Reply...
From: tk
I can confirm this is Lazarus problem only. One time resizing of the KMemo fixes this, now to find out what is the cause.
inserted: 2017-01-12 12:41:23   Reply...
From: СМ
Indeed, it occurs that adding
  KMemo1.Width:=KMemo1.Width+1;
  KMemo1.Width:=KMemo1.Width-1;
even *before* creating the table solves the issue. Probably dimensions are improperly stored somewhere upon creation of the form?
inserted: 2017-01-12 14:36:33   Reply...
From: tk
Found the reason: Bad fix in kcontrols.pas made in r258: "Scrollable controls: Fixed dragging in Lazarus designer.". Hopefully now ok (it is hard to test these issues, LCL is different from VCL, then differences between LCL widgetsets etc. Found a bug in Carbon widgetset: http://bugs.freepascal.org/view.php?id=30910 and another bug in this widgetset regarding the caret, will try to isolate later).
inserted: 2017-01-12 16:00:10   Reply...
From: СМ
Thanks for the fixes!
So far it seems okay here (Lazarus on Win 7).

Just for the record, there is just one minor flaw:
 - The distance between the left border of the table and the left border of the TKMemo is 6 pixels.
 - The distance between the top border of the table and the top border of the TKMemo is 6 pixels.
 - The distance between the RIGHT border of the table and the right border of the TKMemo is 5 pixels.

I suppose these values are hardcoded to 6, so the distance on the reight shall also be 5 (not 6).
inserted: 2017-01-12 20:17:29   Reply...
From: tk
Indeed there still was a glitch, the scrollbar ranges were calculated slightly incorrectly in some cases! I modified the scrollbar range calculations for KMemo.

I did not see that before because recently I always used a wide padding for the document area (it is not hardcoded to 5 but default value is 5 as you can see in TKCustomMemo.Create, note also there is some non-client area - window border - of the KMemo window that might use the same color as KMemo background color, so it might confuse when doing exact pixel calculations). You can change that padding by eg. TKMemo.ContentPadding.All := 20 and you get 20 pixels padding on all sides.

Anyway, great testing, thank you!
inserted: 2017-01-13 11:15:53   Reply...
From: СМ
„note also there is some non-client area - window border - of the KMemo window that might use the same color as KMemo background color‟
Indeed, there is always 1 pixel at least between both borders, so actual displayed distance is 1 + ContentPadding
I have set
   KMemo.ContentPadding.All := 0;
   KMemo.BorderStyle := BsNone;
and now everything looks just as I want it to ;)
inserted: 2017-01-15 14:37:06   Reply...
From: tk
I had to revert some things about table layout calculation back. Column scaling did not work as I needed for one my project. But your sample still works for me. I further improved the size calculation for merged cells, you may check it out. However, the algorithm still has potential for improvements, it does not yet behave eg. the way web browser table algorithms do.
inserted: 2017-01-16 11:58:59   Reply...
From: см
I tried the latest release, there seemed to be some problems, but I have found problems in my code and now they are gone.
One of the problems was that the scrollbar moved to the middle of the table after reaching the bottom of the table (when keeping PGDown pressed).
It occurred that I had an unused row (actually the last one), for which I have not done FixEmptyBlocks. When I removed it, the scrolling issue disapeared.
But maybe it would be useful to have a FixEmptyBlocks routine applying to the entire table?
inserted: 2017-01-17 11:45:57   Reply...
From: tk
Yes, some FixEmptyCells or so could prove useful.
inserted: 2017-01-09 16:14:34   Reply...
From: СМ
Hi Tk,
I am adding images in table cells (in tables in TKMemo).
I need to rezise them keeping the proportions.
I try to use the code given below.
It does not work, because I use KMemo1.LockUpdate . Without it it works.
I wonder if this behaviour is proper (return ImgBlock.Width and ImgBlock.Height when the table is locked) or is this a bug?
I also wonder which is the best way to resize the images?
I could unlock the table and lock it after adding the image, but I guess it will decrease performance.


procedure TForm1.Button1Click(Sender: TObject);
var
    aMemoTable: TKMemoTable;
    imgblock: TKMemoImageBlock;
    Ratio: integer;
    debvar: integer;
begin
  aMemoTable:=KMemo1.Blocks.AddTable;

  KMemo1.LockUpdate;

  aMemoTable.ColCount:=5;
  aMemoTable.rowCount:=5;
  aMemoTable.ColWidths[2]:=20;
  aMemoTable.Cells[1,1].Blocks.AddTextBlock ('1;1') ;
  aMemoTable.Cells[3,3].Blocks.AddTextBlock ('3;3') ;
  aMemoTable.Cells[1,3].Blocks.AddTextBlock ('1;3') ;

 ImgBlock:= aMemoTable.Cells[2,2].Blocks.AddImageBlock('c:\tempimg.jpg'); // ADD AS URL
 debvar:= ImgBlock.Width;
 debvar:= ImgBlock.Height;

  imgblock:= aMemoTable.Cells[2,2].Blocks.AddImageBlock('c:\tempimg.jpg'); // ADD AS URL
  Ratio:= trunc(imgblock.Width/imgblock.height);
  imgblock.ExplicitWidth:=100;
  imgblock.ExplicitHeight:=100*Ratio;

   KMemo1.unLockUpdate;
end;
inserted: 2017-01-09 16:37:43   Reply...
From: СМ
It is me again. I have found a solution: use „imgblock.Image.Width‟ instead of „imgblock.Width‟.
inserted: 2017-01-09 21:07:33   Reply...
From: tk
You did well (you could also use ImageWidth/ImageHeight). To use generic Block.Width KMemo needs to update(measure) the document first, which is blocked inside the LockUpdate/UnlockUpdate pair. Many other TKMemo...Block and/or TKMemoBlocks properties do not work here and need the document update as well.
inserted: 2017-01-10 11:41:41   Reply...
From: СМ
It does not get clear from documentation- are images converted to RTF and then displayed or in the RTF is added a hyperlink to them?
Is it possible to use both ways?
inserted: 2017-01-10 15:08:21   Reply...
From: tk
I do not fully understand what you want to do, or how this corresponds with the original question, but RTF streaming has nothing to do with image painting.

In RTF, images are stored at the position where they appear in the document. Furthermore, Word adds many backward compatibility tags to saved images and saves the image twice (eg. for png it saves the image as png and then as old styled wmf). This is because eg. Wordpad cannot read the png but only the old wmf (even Wordpad distributed with Windows 10, welcome to the M$ world!).

You would have to study RTF specification for more details but even this spec. does not say everything and you have to study saved RTF documents.
inserted: 2017-01-10 15:44:03   Reply...
From: СМ
It is not really related to the previous thread, but since it is related to images I did not start a new one.
What I meant is, that images can:
  Method 1. Be converted to something, then added (hardcoded) in the RTF file. This way the RTF will be displayable as a standalone file.
  or
  Method 2. Images can not be stored in the RTF, but accessed from an external resource. I googled this way of usage, which I have used some time ago: {\field{\*\fldinst{INCLUDEPICTURE "c:\\\\filename.bmp" MERGEFORMAT \\d \\w3000 \\h4500 \\pm1 \\px0 \\py0 \\pw0}}}

After posting the question, I have found experimentally, what you have explained above: method 1 is used, but it would be good to be mentioned in documentation of TKMemo.
When possible, I will try if method 2 is usable with TKMemo, as I assume that it would be away faster in some cases.
inserted: 2017-01-10 23:07:18   Reply...
From: tk
I did not know about method 2. KMemo only supports method 1 now. To use method 2 RTF streaming would need some changes and KMemo as well (to store referenced image list etc.). INCLUDEPICTURE field is mentioned in the RTF specification 1.9 but no additional info is available. I am not very happy to implement something that is not specified.
inserted: 2017-01-11 09:25:39   Reply...
From: СМ
Thanks for the info.
Since no one asked before, support for linked images would not be much demanded, unlike some other feaures.
inserted: 2017-01-04 10:29:20   Reply...
From: СМ
Hi,
Is it possible to make a column in a table in a TKMEMO as narrow as possible to fit the text within?
It occurs that MyTable.Cells[0,0].CurrentRequiredHeight and MyTable.Cells[0,0].RequiredHeight gives some other information, so they cannot be used to determine the required width?
inserted: 2017-01-04 23:15:38   Reply...
From: tk
Currently not, there is no column autosizing implemented. Now it is only possible to specify fixed column width with Table.ColWidths. The fixed column width will be respected if the table fits into KMemo window.

There is also possible to set fixed width of entire table but it is still somewhat buggy.
inserted: 2017-01-06 08:38:37   Reply...
From: СМ
Thanks! I will try to find a workaround for the timebeing.
inserted: 2017-01-04 08:41:02   Reply...
From: СМ
Hi Tk,
When executing the code below, the Block Border (gray one) on the left and bottom is within the borders of the individual cells.
I have found a workaround with
    MyTable.BlockStyle.LeftMargin:=-4;
    MyTable.BlockStyle.BottomMargin:=-4;
but I guess there is actually a bug in this case?



procedure TfrmMain.Button6Click(Sender: TObject);
var
  MyTable: TKMemoTable;
  row: integer;
  clm: integer;
begin
  kmMain.Blocks.clear;
  MyTable:= kmMain.Blocks.AddTable;
  MyTable.ColCount:=5 ;
  MyTable.rowCount:=5 ;
  MyTable.CellStyle.LeftMargin:=1;
  MyTable.CellStyle.rightMargin:=1;
  MyTable.CellStyle.TopMargin:=1;
  MyTable.CellStyle.BottomMargin:=1;

  MyTable.BlockStyle.BorderColor:=clLtGray;
  MyTable.BlockStyle.BorderWidth:=2;
  MyTable.ApplyDefaultCellStyle;

  for row:=0 to 4 do
    for clm:=0 to 4 do
    begin
       MyTable.Cells[clm,row].Blocks.AddTextBlock (IntToStr(row) + ';' + IntToStr(clm));
       MyTable.Rows[Row].Cells[Clm].BlockStyle.BorderWidth:=1;
    end;
end;
inserted: 2017-01-04 22:55:21   Reply...
From: tk
Yes there was bug, I've fixed this already.
inserted: 2016-12-27 15:45:46   Reply...
From: Josh
KGRID and OSX ?
Hi,
I am using latest lazarus trunk and bitbucket version of Controls, I can copile and add the kcontrols to lazarus, the problem is that I have a windows project that has a few kgrid that compile and run under windows; when I compile prject on osx; after setting compile options for osx; when I choose compile it starts to compile but then lazarus abrubptly terminates without generating an error. I cannot then open the project again; as soon as it starts to open project it then again abruptly terminates. If I remove the grids from the project on windows mahine and then open it on OSX te applicaton will open and compile and run. As soon as I add a kgrd; have major issue on OSX.

Sorry for the wall of text; just trying to explain as best as I can.
inserted: 2016-12-27 23:40:45   Reply...
From: tk
And the KGrid demo project opens/runs fine?

Note 1. There is an imaging bug on OSX in the TKAlphaBitmap that is used for misc. imaging in KControls, with all relevant images painted incorrectly.

Note 2. I only tested KControls on a virtual MAC with El Capitan. Don't have access to a real MAC. But except for the above problem all demos compile/run fine.
inserted: 2017-01-02 20:30:21   Reply...
From: tk
The imaging bugs were fixed in the trunk.
inserted: 2016-12-19 12:07:17   Reply...
From: СМ
Hi,
I am trying to do the following:
When a double click is done in a cell to determine the clicked cell (or row) and to do something with its contents. I actually need the row index.

But I've come across 2 problems:
1. I have
var
...
  TBL: TKMemoTable;
begin
...
  TBL:= kmMain.Blocks.AddTable;
  tbl.OnDblClick:= @OnTableDblClick;

With this code the OnTableDblClick is never executed. In other words the OnDoubleCLick event is not firing.
For example if I do kmMain.OnDblClick:= @OnTableDblClick; the event is firing.

2. I cannot determine in which cell/row the DoubleCLick occurs.
The good old way
   for ...
     if cell[x,y].active is not present.
Maybe I could use something else?
inserted: 2016-12-21 09:51:51   Reply...
From: tk
Hmm, this appears to be a little bit tricky. Because the table is basically a set of nested containers and OnDblClick is called only once and for the innermost block/container, you have to use the new TKMemo.OnBlockDblClick and search for a block of interest:

...
KMemo1.OnBlockDblClick := EventBlockDblClick;
...

procedure TMainForm.EventBlockDblClick(Sender: TObject; ABlock: TKMemoBlock;
  var Result: Boolean);
var
  Block: TKmemoBlock;
begin
  Block := ABlock;
  while (Block <> nil) and not (Block is TKMemoTableCell) do
    Block := Block.ParentBlocks.Parent;
  // Block is either nil or TKMemoTableCell here
  if Block <> nil then
  begin
    // do your stuff
    Result := True;
  end;
end;

Please also download the newest fix from trunk. The event was not firing for the cell area not occupied by the cell content.

You may also use the new TKMemoTableCell's read only properties ColIndex and RowIndex to find the cell's position in the table.
inserted: 2016-12-23 08:07:22   Reply...
From: СМ
Once again, thanks for the support!
As far as I have used it t works fine.
But it is tricky indeed... it occurs that if I click in a nested table I gets the cell in the nested table instead of the parent one (makes perfect sense). I still have not thought about that and if it will be a serious obstacle.

Current TKMemo documentation says, that nested tables are not supported, but so far I've had no troubles with them (except that I do not know how to provide some distance between them and the parent ones). Is it because doc is not updated?
inserted: 2016-12-23 11:12:33   Reply...
From: tk
Nested tables are supported in KMemo but you won't be able to load/save them from/to RTF.

The doc is not ready by far, only the short introductory document. There are still important features to be done in KMemo so I don't want to write the doc until they're finished.

You should be able to find the cell in the main table if you click on the nested table, but you have to extend the logic in EventBlockDblClick, eg. (writing from memory, haven't tried):

procedure TMainForm.EventBlockDblClick(Sender: TObject; ABlock: TKMemoBlock;
  var Result: Boolean);
var
  Block: TKMemoBlock;
  Cell: TKMemoTableCell;
  WeAreInNestedTable: Boolean;
  Row, Col: Integer;
begin
  Cell := nil;
  // find nearest table
  Block := ABlock;
  while (Block <> nil) and not (Block is TKMemoTable) do
  begin
    if Block is TKMemoTableCell then
      Cell := Block as TKMemoTableCell; // this is the innermost cell (either in nested or main table)
    Block := Block.ParentBlocks.Parent;
  end;
  WeAreInNestedTable := (Block <> nil) and (Block.ParentBlocks.Parent is TKMemoTableCell);
  if WeAreInNestedTable then
    Cell := Block.ParentBlocks.Parent as TKMemoTableCell;
  if Cell <> nil then
  begin
    // Here Cell is always in the main table
    Col := Cell.ColIndex;
    Row := Cell.RowIndex;
    // do your stuff
    Result := True;
  end;
end;
inserted: 2016-12-23 11:46:51   Reply...
From: СМ
Thanks, I have just managed to do it myself by looping up once again until I reaching a higher level ;)
inserted: 2016-12-23 11:49:44   Reply...
From: СМ
Exact solution is

...
begin
  Block := ABlock;
  while (Block <> nil) and not (Block is TKMemoTableCell) do //Search up until parent is a table cell
    Block := Block.ParentBlocks.Parent;
  // Block is either nil or TKMemoTableCell here
  if Block <> nil then //search one level up to check if the tabel is nested
  begin
    BlockNested:= Block.ParentBlocks.Parent;
    while (BlockNested <> nil) and not (BlockNested is TKMemoTableCell) do //Search up until parent is a table cell
       BlockNested := BlockNested.ParentBlocks.Parent;
   end;
  if (BlockNested is TKMemoTableCell) then
  begin
    Block:= BlockNested;
  end;
  begin
    // do your stuff
...

Of course, searching up until findind the topmost table could be implemented, but in my case I am sure, that I have only 1 nesting level.
Older comments
My account
Recently modified

KControls Component Suite

by: tk

2015-11-16

KHexEditor

by: tk

2010-11-08

KGrid

by: tk

2010-11-08

KIcon

by: tk

2009-11-24

KGrid 1.3 released.

by: tk

2009-08-10

Recently inserted

ONEinspect

by: tk

2016-04-12

Grouping of comments

by: tk

2015-11-16

KMemo

by: tk

2015-08-12

My recent work on KMemo

by: tk

2015-07-28

Update for RAD Studio XE2

by: tk

2012-04-03