Using TBookmarklist question lazarus / 16-Databases ---------------------------------------------------------------------- daveinhull · 2018-12-28 17:58 Hi, I'm using a TBookmarklist to manage tickboxes in a DB Grid. So the DBGrid has two fields, the TBookmarklist in the first one and the actual database field I'm interested in selecting in the second. All this is being done in a modal form. So OnCreate I 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   RecList1 := TBookmarkList.Create(DbGrid1); where RecList1 is defined as 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     RecList1: TBookmarklist; Then in the DBGrid UserCheckboxState I do 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 TForm2.DBGrid1UserCheckboxState(Sender: TObject; Column: TColumn; var AState: TCheckboxState);begin  if RecList1.CurrentRowSelected then    AState := cbChecked  else    AState := cbUnchecked;end; and in the DBGrid CellClick I do 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 TForm2.DBGrid1CellClick(Column: TColumn);begin  If Column.Index=0 then    RecList1.CurrentRowSelected := not RecList1.CurrentRowSelected;end;   On the main form I press a button and it shows this form Modal and everything works well. I have a button which cancels the Modal form as 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   ModalResult := mrCancel; But the next time I press the main form button to ShowModal this form I get an error External SIGSERV This only happens if I actually select some of the tickboxes the first time I show the form, i.e. I can show and close the form as many times as I want so long as I don't select any tickboxes. I think it must have something to do with memory getting released maybe when the form is hidden (I assume it is hidden when I ModalResult := mrCancel as the create routine isn't called again.) Anyone got any thoughts in this? Thanks Dave ---------------------------------------------------------------------- daveinhull · 2018-12-29 18:04 Some further information: It would appear that the cause of this problem is if I close and then re-open the dataset associated with the grid that is connected to the Bookmarklist and the issue is in DBGrids (I think), but I'm just not good enough to find out what is going on. Any help? Thanks ---------------------------------------------------------------------- daveinhull · 2018-12-29 18:16 Ok, so a little bit more confident than I thought and traced the code through to 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 VisitAll;  begin    AIndex := 0;    i := 0;    while ipointer(@TDataset.CompareBookmarks);           // Note.       //       // fpc help say CompareBookmarks should return -1, 0 or 1 ... which imply that       // bookmarks should be a sorted array (or list). In this scenario binary search       // is the prefered method for finding a bookmark.       //       // The problem here is that TBufDataset and TSQLQuery (and thus TCustomSQLQuery       // and TCustomBufDataset) CompareBookmarks only return 0 or -1 (some kind of       // is this a valid bookmark or not), the result is that it appears as an unsorted       // list (or array) and binary search should not be used.       //       // The weird thing is that if we use MyCompareBookmarks which deals with comparing       // the memory reserved for bookmarks in the hope bookmarks are just some kind of       // reocord indexes, currently work fine for TCustomBufDataset derived datasets.       // however using CompareBookmarks is always the right thing to use where implemented.       //       // As Dbgrid should be TDataset implementation agnostic this is a way I found       // to know if the dataset is derived from TCustomBufDataset or not.       // Once TCustomBufDataset is fixed, remove this ugly note & hack.       case FDataset.ClassName of         'TSQLQuery','TBufDataset','TCustomSQLQuery','TCustomBufDataset':           FCanDoBinarySearch := false;         else           FCanDoBinarySearch := true;       end; Which suggests that TSQLQuery is a funny dataset and doesn't comply with the CompareBookmarks return values (see comments). But TMethod does return True. So at the end of this routine, FUseCOmpareBookmarks is True and FCanDoBinarySearch is False. In the TBookmarklist.Find routine there is this code Code: Pascal  [Select]       procedure VisitAll;       begin         AIndex := 0;         i := 0;         while i