How can get scroll position of DBGrid ? lazarus / 16-Databases ---------------------------------------------------------------------- majid.ebru · 2017-06-12 09:33 Hi i put a DBGrid in form and it has Verticalscrol and HorizentalScroll. how can i get postion of Scroll's DBGrid?? ---------------------------------------------------------------------- Handoko · 2017-06-12 11:55 As far as I know, we cannot access the positions of DBGrid's scrollbars. Why do you need the values? Can you please explain more. Alternatively, both TStringGrid and TDrawGrid have TopRow to get the first row that showing on the grid. It may not the best thing to do but if you 'really' need to get the vertical scrollbar position, you can try to replace TDBGrid with TStringGrid. The downside is, you have to provide the code manually to load data from database to TStringGrid and that is not easy. ---------------------------------------------------------------------- majid.ebru · 2017-06-12 12:18 Thank you i put a scrollbox on top of DBGrid and put it some editbox. i want to  search text in each colume. but if i move verticalscroll of dbgrid , i can't move verticalscrollbox becuase i haven't verticalscroll position of DBgrid. . so i should an other way to search each colum. ---------------------------------------------------------------------- Handoko · 2017-06-12 12:30 Did you mean you put a TScrollBox on the TDBGrid? You cannot use TScrollBox to scroll the things inside TDBGrid. What did  you want to do? Do you want to do item searching for the database? User type something in a TEdit and the result will be shown in a grid? ---------------------------------------------------------------------- majid.ebru · 2017-06-12 12:36 Quote from: Handoko on June 12, 2017, 02:30:07 pmDid you mean you put a TScrollBox on the TDBGrid? You cannot use TScrollBox to scroll the things inside TDBGrid. No.i can't put a TScrollBox on the TDBGrid Quote from: Handoko on June 12, 2017, 02:30:07 pm Do you want to do item searching for the database? User type something in a TEdit and the result will be shown in a grid? YES ---------------------------------------------------------------------- mangakissa · 2017-06-12 12:56 Build a searchoption on top of the first cells of tdbgrid. Or use a tpanel, a tcombobox, a teditbox and a button for searching in the dataset (note: TDBrid only visualize your data). ---------------------------------------------------------------------- majid.ebru · 2017-06-12 13:04 Quote from: mangakissa on June 12, 2017, 02:56:01 pmBuild a searchoption on top of the first cells of tdbgrid. Or use a tpanel, a tcombobox, a teditbox and a button for searching in the dataset (note: TDBrid only visualize your data). yes i want to this. . but my fields are 65 fields and i can't show all of them . so i put a TScrollBox and put  this some panels and edit. ---------------------------------------------------------------------- howardpc · 2017-06-12 14:34 Attached is a small example showing how locating a specific record in a dataset via a TEdit entry can scroll a dbgrid display. ---------------------------------------------------------------------- Handoko · 2017-06-12 15:29 I tried something different, show all results in a TListBox. Note: I'm not good in database programming, I use only the easiest TDbf. ---------------------------------------------------------------------- majid.ebru · 2017-06-12 19:18 thank you i want like this : ---------------------------------------------------------------------- Handoko · 2017-06-12 20:02 If I want to do the thing like the picture you showed, I will do like this: 01. Load all data into a StringGrid 02. Ask user to provide the filter string and which column to search 03. Compare each cell in the column with the filter string 04. If found, save the results of the row index into an array of integer 05. Now you have the column position and the array of integer 06. Highlight the cell using TStringGrid.OnPrepareCanvas It's not hard, right? But you need to know how to load and save data to StringGrid, compare cell with data, save the result in an array and do cell highlight. ---------------------------------------------------------------------- mangakissa · 2017-06-13 06:47 If you want to show a filter on the first row, you have to develop it self. But there are alternatives like kgrid ---------------------------------------------------------------------- Handoko · 2017-06-13 07:47 Quote from: majid.ebru on June 12, 2017, 02:18:27 pmso i should an other way to search each colum. What you said can have 2 meanings: - Search items inside a column - Locate a column by its name The icon in the picture you shown previously is called filtering. Filtering is not the same as searching. Filtering means to hide cells/columns/rows that do not pass the test condition. If what you want is searching, I've made an example for you. It used a TStringGrid. TStringGrid is much powerful than DBGrid, but you need to provide your code. If it is not enough, you may try KGrid as recommended by @mangakissa. My example does not show you how to do filtering. But if you already understand how the code work, it won't be hard to modify it to support filtering. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Graphics, dbf, db, Forms, StdCtrls, ExtCtrls, ComCtrls,  Grids; type   { TForm1 }   TForm1 = class(TForm)    btnOpen: TButton;    btnSearch: TButton;    DataSource1: TDataSource;    Dbf1: TDbf;    Label1: TLabel;    LabeledEdit1: TLabeledEdit;    RadioGroup1: TRadioGroup;  StatusBar1: TStatusBar;    StringGrid1: TStringGrid;    procedure btnOpenClick(Sender: TObject);    procedure btnSearchClick(Sender: TObject);    procedure StringGrid1Click(Sender: TObject);    procedure StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;      aState: TGridDrawState);  end; const  DataFileName = 'MyData.dbf'; type  TPosition = record    Col: Integer;    Row: Integer  end; var  Form1: TForm1;  Results: array of TPosition; implementation {$R *.lfm} { TForm1 } procedure TForm1.btnOpenClick(Sender: TObject);var  i: Integer;begin   // Open the database  Dbf1.FilePathFull := ExtractFileDir(ParamStr(0));  Dbf1.TableName := DataFileName;  Dbf1.Open;   // Set StringGrid's row and column  StringGrid1.RowCount := Dbf1.RecordCount + 1;  for i := 1 to Dbf1.FieldCount do  begin    StringGrid1.Columns.Add;    StringGrid1.Columns[i-1].Title.Caption := Dbf1.FieldDefs[i-1].Name;  StringGrid1.Columns[i-1].Title.Alignment := taCenter;    StringGrid1.Columns[i-1].Title.Font.Style := [fsBold];    StringGrid1.Columns[i-1].Width := 120;  end;   // Load data to StringGrid  Dbf1.First;  while not(Dbf1.EOF) do  begin    StringGrid1.Cells[0, Dbf1.RecNo] := IntToStr(Dbf1.RecNo);    for i := 0 to (Dbf1.FieldCount-1) do      StringGrid1.Cells[i+1, Dbf1.RecNo] := Dbf1.Fields[i].AsString;    Dbf1.Next;  end;   // Close the database  Dbf1.Close;   StringGrid1.Enabled := True;  btnOpen.Enabled := False;  Label1.Visible := True;  Height := 380;  StringGrid1Click(Sender); // Show row:column info and paint header color end; procedure TForm1.btnSearchClick(Sender: TObject);var  c, r: Integer;begin   // Abort search if user does not provide text to search  if (LabeledEdit1.Text = '') then  begin    StatusBar1.SimpleText := ' Error, please provide search text.';    Exit;  end;   // Search items in a column  if (RadioGroup1.ItemIndex = 0) then  begin    SetLength(Results, 0);    for r := 0 to (StringGrid1.RowCount-1) do  begin      if Pos(LabeledEdit1.Text, StringGrid1.Cells[StringGrid1.Col, r]) > 0 then      begin        SetLength(Results, Length(Results)+1);        Results[High(Results)].Col := StringGrid1.Col;        Results[High(Results)].Row := r;      end;    end;    StringGrid1.Repaint;    StatusBar1.SimpleText :=      ' Search result: ' + IntToStr(Length(Results)) + ' item(s).';;  end;   // Search all  if (RadioGroup1.ItemIndex = 1) then  begin    SetLength(Results, 0);  for c := 0 to (StringGrid1.Columns.Count-1) do      for r := 0 to (StringGrid1.RowCount-1) do      begin        if Pos(LabeledEdit1.Text, StringGrid1.Cells[c, r]) > 0 then        begin          SetLength(Results, Length(Results)+1);          Results[High(Results)].Col := c;          Results[High(Results)].Row := r;        end;      end;    StringGrid1.Repaint;    StatusBar1.SimpleText :=      ' Search result: ' + IntToStr(Length(Results)) + ' item(s).';;  end; end; procedure TForm1.StringGrid1Click(Sender: TObject);var  i: Integer;begin   // Show StringGrid's row:column position  Label1.Caption := IntToStr(StringGrid1.Row) +':'+ IntToStr(StringGrid1.Col);   // Change StringGrid header color  for i := 0 to (StringGrid1.Columns.Count-1) do    if (i = StringGrid1.Col-1) then      StringGrid1.Columns[i].Title.Font.Color := clRed    else      StringGrid1.Columns[i].Title.Font.Color := clBlack;   // Change info in search method option  RadioGroup1.Items[0] := StringGrid1.Columns[StringGrid1.Col-1].Title.Caption; end; procedure TForm1.StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;  aState: TGridDrawState);var  i: Integer;begin   if not(sender is TStringGrid) then Exit;   // Paint the background yellow for the results  for i := Low(Results) to High(Results) do    if (Results[i].Col = aCol) and (Results[i].Row = aRow) then      (sender as TStringGrid).Canvas.Brush.Color := clYellow; end; end. ---------------------------------------------------------------------- Thaddy · 2017-06-13 08:41 In general, you would not want to use scroll positions over a whole database. You should want to get rid of the scrollbars altogether. In database programming, scrollbars are evil. Except maybe on a small selection of 10.000 records. ---------------------------------------------------------------------- majid.ebru · 2017-06-13 17:48 Thanks . i don't like use component( because i want wirte code myself). . i thinck there isn't deferent between search and filter. . i just want that Tedit exactly stay on culome and when user move scroll of DBGrid,i can move it. . ok.i try to use TStringGrid. . thanks every body ---------------------------------------------------------------------- mangakissa · 2017-06-14 07:38 TStringgrid is not the option for records on your dataset. Yes, TDBGrid derives from TStringgrid, but has extra layer for selecting / showing your requested data. ---------------------------------------------------------------------- Handoko · 2017-06-14 08:33 I just checked the documentation, TDBGrid does not derive from TStringGrid. They only share a common ancestor TCustomGrid: http://lazarus-ccr.sourceforge.net/docs/lcl/dbgrids/tdbgrid.html I saw TDBGrid has OnPrepareCanvas too, it may be able to do the background color highlight. Using TDBGrid has its own advantages, it makes the data loading and saving automatically. But in TS case, I recommend to use TStringGrid not TDBGrid because: - To achieve what TS want we need something more flexible than TDBGrid. For example in TStringGrid we can easily get and move the active cell to other row or column using code, and we can do multiple selections. I can't found it in TDBGrid. - If for simply showing or editing data, I recommend to use TDBGrid. But if for doing search or filtering, I think it will be better to load data from database, disconnect it. And let users to manipulate the data and give them "Reload Data", "Save" and "Save As" features. It will prevent users accidentally mess up the data also good for preventing database error/corrupt when power failure happens when it opened for a long period of time. I can be wrong, that's just my 2 cents. Quote from: majid.ebru on June 13, 2017, 07:48:47 pmi just want that Tedit exactly stay on culome and when user move scroll of DBGrid,i can move it. It can be done using TStringGrid. You need use TStringGrid.Option > enable goEditing. Also you have to add more smarter codes: - When loading data skip showing it on the first row in the TStringGrid, because it is used for searching. - Check if the cells in the first row, if it is not empty then do the searching. - Add code to prevent users to edit data (or lock) cells other than first row. My previous example shows to how to search data if user provide text in LabelEdit1. You need to modify the code to read data from first-row cells of each coloumn. ---------------------------------------------------------------------- mangakissa · 2017-06-14 08:57 Quote from: majid.ebrui thinck there isn't deferent between search and filter.Define search: When searching on a particular value, the cursor of the dataset jumps to the first founded record Define Filter: When searching on a particular value, only the records that matches are visible on screen. QuoteTo achieve what TS want we need something more flexible than TDBGrid. For example in TStringGrid we can easily get and move the active cell to other row or column using code, and we can do multiple selections. I can't found it in TDBGrid.TDBGrid can select multiple selections. With TStringgrid you're really disconnected from the dataset. Locating records for updating is a lot more work to get the right record to be modified.  Therefore you have at least a primary key to find the right record. It's his choice. I have somewhere code from a TDBGrid that has an filter/search built in. I shaw look at it. ---------------------------------------------------------------------- Handoko · 2017-06-14 09:09 Quote from: mangakissa on June 14, 2017, 10:57:24 amWith TStringgrid you're really disconnected from the dataset. Locating records for updating is a lot more work to get the right record to be modified.  Therefore you have at least a primary key to find the right record. Okay, I can see your points. Quote from: mangakissa on June 14, 2017, 10:57:24 amI have somewhere code from a TDBGrid that has an filter/search built in. I shaw look at it. It would be great if you are willing to show us or at least explain the basic things how it works. Database programming is not my expertise, I spend most of my time playing with graphics and other time-wasting things. ---------------------------------------------------------------------- Handoko · 2017-06-14 13:03 @majid.ebru I've modified the code. Now the search box is inside the grid, you can see a pale green row. Type your search text there and it will automatically do searching. You can do multiple column search. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Graphics, dbf, db, Forms, StdCtrls, ExtCtrls, ComCtrls,  Grids, Dialogs; type   { TForm1 }   TForm1 = class(TForm)    btnOpen: TButton;    DataSource1: TDataSource;    Dbf1: TDbf;    Label1: TLabel;    StringGrid1: TStringGrid;    procedure btnOpenClick(Sender: TObject);    procedure StringGrid1Click(Sender: TObject);    procedure StringGrid1EditingDone(Sender: TObject);    procedure StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;      aState: TGridDrawState);  end; const  DataFileName = 'MyData.dbf'; type  TPosition = record    Col: Integer;    Row: Integer  end; var  Form1: TForm1;  Results: array of TPosition; implementation {$R *.lfm} { TForm1 } procedure TForm1.btnOpenClick(Sender: TObject);var  i: Integer;begin   // Open the database  Dbf1.FilePathFull := ExtractFileDir(ParamStr(0));  Dbf1.TableName := DataFileName;  Dbf1.Open;   // Set StringGrid's row and column  StringGrid1.RowCount := Dbf1.RecordCount + 2; // +2 because it includes header and search row  for i := 1 to Dbf1.FieldCount do  begin    StringGrid1.Columns.Add;    StringGrid1.Columns[i-1].Title.Caption := Dbf1.FieldDefs[i-1].Name;  StringGrid1.Columns[i-1].Title.Alignment := taCenter;    StringGrid1.Columns[i-1].Title.Font.Style := [fsBold];    StringGrid1.Columns[i-1].Width := 120;  end;   // Load data to StringGrid  Dbf1.First;  while not(Dbf1.EOF) do  begin    StringGrid1.Cells[0, Dbf1.RecNo+1] := IntToStr(Dbf1.RecNo);    for i := 0 to (Dbf1.FieldCount-1) do      StringGrid1.Cells[i+1, Dbf1.RecNo+1] := Dbf1.Fields[i].AsString;    Dbf1.Next;  end;   // Close the database  Dbf1.Close;   StringGrid1.Enabled := True;  StringGrid1.AutoAdvance := aaNone; // Disable it to prevent problem  btnOpen.Enabled := False;  Label1.Visible := True;  StringGrid1Click(Sender); // Show row:column info end; procedure TForm1.StringGrid1Click(Sender: TObject);var  ActiveRow, ActiveCol: Integer;  i: Integer;begin   ActiveRow := StringGrid1.Row;  ActiveCol := StringGrid1.Col;   // Allow editing on first row  if (ActiveRow = 1) then    StringGrid1.Options := StringGrid1.Options+[goAlwaysShowEditor, goEditing]  else    StringGrid1.Options := StringGrid1.Options-[goAlwaysShowEditor, goEditing];   // Show row:column information  Label1.Caption := 'R:C = ' + IntToStr(ActiveRow-1) +':'+ IntToStr(ActiveCol);   // Change selected column's header text color  for i := 0 to (StringGrid1.Columns.Count-1) do    if (i = StringGrid1.Col-1) then    StringGrid1.Columns[i].Title.Font.Color := clWhite    else      StringGrid1.Columns[i].Title.Font.Color := clBlack; end; // Use OnEditingDone to do searchingprocedure TForm1.StringGrid1EditingDone(Sender: TObject);var  SearchText: string;  c, r: Integer;begin  SetLength(Results, 0);  for c := 1 to StringGrid1.Columns.Count do  begin    SearchText := StringGrid1.Cells[c, 1];    if (SearchText <> '') then    begin      for r := 2 to (StringGrid1.RowCount-1) do      begin        if Pos(SearchText, StringGrid1.Cells[c, r]) > 0 then        begin        SetLength(Results, Length(Results)+1);          Results[High(Results)].Col := c;          Results[High(Results)].Row := r;        end;      end;      StringGrid1.Repaint;    end;  end;end; procedure TForm1.StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;  aState: TGridDrawState);var  i: Integer;begin   if not(sender is TStringGrid) then Exit;   // Background of the search row is moneygreen  if (aRow = 1) and (aCol > 0) then    (sender as TStringGrid).Canvas.Brush.Color := clMoneyGreen;   // If search cell has text, change the cell color to red  if (aRow = 1) and (StringGrid1.Cells[aCol, aRow] <> '') then    (sender as TStringGrid).Canvas.Brush.Color := clAqua;   // Highlight selected column's header with green  if (aRow = 0) and (aCol = StringGrid1.Col) then    (sender as TStringGrid).Canvas.Brush.Color := clGreen;   // Background of search result cells is yellow  for i := Low(Results) to High(Results) do    if (Results[i].Col = aCol) and (Results[i].Row = aRow) then    begin      (sender as TStringGrid).Canvas.Brush.Color := clYellow;      Exit; // Exit immediately after found, to improve performance    end; end; end. ---------------------------------------------------------------------- majid.ebru · 2017-06-17 13:06 thank you very much. now : how can i change Appearance search row like This or This ---------------------------------------------------------------------- Handoko · 2017-06-17 13:22 I never tried but I think it is possible. You may need to use TDrawGrid. In TStringGrid we can change the appearance but very limited, only color and font. Using TDrawGrid you can draw the appearance to whatever you like. ---------------------------------------------------------------------- mangakissa · 2017-06-19 07:06 Download this DBGrid. Look at the source and try it yourself. ---------------------------------------------------------------------- Handoko · 2017-06-19 07:16 Downloaded and tested. But I don't know how to make Delphi code works on Lazarus. Anyway, I visited the website, it looks great. ---------------------------------------------------------------------- majid.ebru · 2018-09-22 11:50 Quote from: Handoko on June 19, 2017, 09:16:52 amDownloaded and tested. But I don't know how to make Delphi code works on Lazarus. Anyway, I visited the website, it looks great. Hi @ Handoko how did you tested it? i can't instal pakage or open project?? thank you ---------------------------------------------------------------------- Handoko · 2018-09-22 12:22 You can convert the delphi project to lazarus project: Lazarus main menu > Tools > Delphi Conversion I use Linux but my Lazarus/FPC is capable to compile Windows projects. Unfortunately, I failed to compile the SMDBGrid demo. I got error: RXUtils.pas(316,9) Error: Identifier not found "TransparentBlt" when compiling this line: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i         TransparentBlt(Dest.Handle, DstX, DstY, DstW, DstH,          Temp.Canvas.Handle, SrcX, SrcY, SrcW, SrcH,          TransparentColor); ---------------------------------------------------------------------- valdir.marcos · 2018-09-22 12:44 Quote from: Handoko on September 22, 2018, 02:22:17 pmI got error: RXUtils.pas(316,9) Error: Identifier not found "TransparentBlt"RX components are already converted to Lazarus. Are you using them from OPM? ---------------------------------------------------------------------- Handoko · 2018-09-22 13:13 Thanks for informing me that the RX components is available on OPM. I've just installed it and 'force' the code to use the installed RXUtils. It seemed the issue has been solved but now I got a new problem: SMDBGrid.pas(193,15) Error: There is no method in an ancestor class to be overridden: "RestoreDefaults;" on the code below (line #40): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TSMDBColumn = class({$IFDEF USE_TNT} TTntColumn {$ELSE} TColumn{$ENDIF})  private    FBandIndex: Integer;     FSortCaption: TSMGString;    FSortType: TSMSortType;    FInplaceEditor: TSMInplaceEditorType;     FFooterValue: Variant;    FFooterType: TSMFooterType;    FFooterText: TSMGString;     FTag: Longint;    FTextEllipsis: TSMTextEllipsis;     FFilterValue: TSMGString;    FFilterList: TStrings;     // Mark a column to be able to get filtered. Eliminates the filter box for this column.    FFilterable: Boolean;     procedure SetFooterValue(Value: Variant);    procedure SetFooterType(Value: TSMFooterType);    procedure SetSortCaption(Value: TSMGString);    procedure SetSortType(Value: TSMSortType);    procedure SetInplaceEditor(Value: TSMInplaceEditorType);    procedure SetFilterValue(const Value: TSMGString);    procedure SetFooterText(const Value: TSMGString);    function GetFilterList: TStrings;    procedure SetFilterList(const Value: TStrings);  protected    intInternalCount: Integer; {required for Avg calculation}     function GetGrid: TSMDBGrid;  public    constructor Create(Collection: TCollection); override;    destructor Destroy; override;     procedure Assign(Source: TPersistent); override;    procedure RestoreDefaults; override;... It seems the code is not very compatible with Lazarus/FPC. ---------------------------------------------------------------------- valdir.marcos · 2018-09-22 13:26 Quote from: Handoko on September 22, 2018, 03:13:51 pmnow I got a new problem: SMDBGrid.pas(193,15) Error: There is no method in an ancestor class to be overridden: "RestoreDefaults;" on the code below (line #40): Since there is nothing to be overridden, just delete the "override;" part and let the "new" RestoreDefaults method be used: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   procedure RestoreDefaults; ---------------------------------------------------------------------- Handoko · 2018-09-22 13:59 Well, removing that "override" keyword solved that issue. But now I got  SMDBGrid.pas(304,17) Error: Identifier not found "TSMGradientDirection": Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   TSMGradientDraw = class(TPersistent)  private    FGrid: TSMDBGrid;    FDirection: TSMGradientDirection; Here, this are the things in the uses clause of SMDBGrid.pas: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit SMDBGrid; {$MODE Delphi} interface {$I SMVersion.inc} {used only if BLOB fields with graphics contains the jpeg's}//{$DEFINE USE_JPEG} {$IFDEF USE_DBEXPRESS}        {$IFNDEF VER_ENTERPRISE}              {$DEFINE VER_ENTERPRISE}        {$ENDIF}{$ENDIF} uses  LCLIntf, LCLType, LMessages, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  Menus, Grids, DBGrids, {$IFDEF USE_TNT} TntDBGrids, {$ENDIF} DB, StdCtrls, SMCnst,  {$IFDEF SMForDelphi6} Variants, {$ENDIF}  {$IFDEF USE_JPEG} Jpeg, {$ENDIF}  RXUtils {ex- VCLUtils from RX-Lib}; And even if the problem above has solved, there still 9 more 7 more errors in the messages window: ---------------------------------------------------------------------- valdir.marcos · 2018-09-22 14:18 Quote from: Handoko on September 22, 2018, 03:59:51 pmWell, removing that "override" keyword solved that issue. But now I got  SMDBGrid.pas(304,17) Error: Identifier not found "TSMGradientDirection"That site has more Delphi free components, maybe what you need is on its TGradientPanel: Freeware SMComponents http://www.scalabium.com/smcmpnts.htm Quote And even if the problem above has solved, there still 9 more 7 more errors in the messages windowUnfortunately, solving that errors is part of the job of converting Delphi components to Lazarus. You are on the right path of solving one by one. Some of them are easy and others are really hard to solve.