[SOLVED] error in Windows but not in Linux lazarus / 34-Windows ---------------------------------------------------------------------- petevick · 2022-02-06 16:07 Can anyone see why the following code fails in Windows but not in Linux ?? 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 TForm1.RefreshTree(Sender: TObject);var  aNode:TTreeNode;  aChild:TTreeNode;  S: String = '';begin  if (myTreeView.Path > '') and  (myTreeView.Path<>myTreeView.Selected.GetTextPath) then  begin  aNode:=myTreeView.Selected.Parent;    S:=myTreeView.Selected.Text;    aChild:=aNode.GetFirstChild;    aNode.Expanded:=False;    aNode.Expanded:=True;    while aChild.Text<>S do        aChild:=aChild.GetNext;    aChild.Selected:=True;  end;end;The error message was as follows... QuoteProject folder raised exception class 'External SICEGV' At address 404144 ---------------------------------------------------------------------- petevick · 2022-02-06 16:21 ...actually it could have something to do with this topic...https://fo rum.lazarus.freepascal.org/index.php/topic,58161.msg433345.html#msg433 345 ....I'll update the ShellCtrls unit and see if the error goes away.... ---------------------------------------------------------------------- rvk · 2022-02-06 16:48 Quote from: petevick on February 06, 2022, 05:07:20 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     while aChild.Text<>S do        aChild:=aChild.GetNext;This is bound to give problems on ALL platforms. If you loop aChild := aChild.GetNext, somewhere down the line aChild will become nil (when there is no next anymore). Don't rely on the fact S always exists. So ALWAYS check if you are at the end. Something like 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 while (aChild <> nil) and (aChild.Text <> S) then  aChild := aChild.GetNext;if aChild <> nil then aChild.Selected := True; ---------------------------------------------------------------------- petevick · 2022-02-06 17:07 Quote from: petevick on February 06, 2022, 05:21:50 pm...actually it could have something to do with this topic...https://forum.lazarus.fre epascal.org/index.php/topic,58161.msg433345.html#msg433345 ....I'll update the ShellCtrls unit and see if the error goes away.... Nope, still getting the error ---------------------------------------------------------------------- petevick · 2022-02-06 17:11 Quote from: rvk on February 06, 2022, 05:48:19 pmQuote from: petevick on February 06, 2022, 05:07:20 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     while aChild.Text<>S do        aChild:=aChild.GetNext;This is bound to give problems on ALL platforms. If you loop aChild := aChild.GetNext, somewhere down the line aChild will become nil (when there is no next anymore). Don't rely on the fact S always exists. So ALWAYS check if you are at the end. Something like 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 while (aChild <> nil) and (aChild.Text <> S) then  aChild := aChild.GetNext;if aChild <> nil then aChild.Selected := True;Yes, you're quite right rvk, the code is more proof of concept before I take it further. I really appreciate the amended code you've added, that'll help a lot ---------------------------------------------------------------------- rvk · 2022-02-06 17:18 Quote from: petevick on February 06, 2022, 06:11:20 pmYes, you're quite right rvk, the code is more proof of concept before I take it further. I really appreciate the amended code you've added, that'll help a lot  If you still get an error you need to see what line the error is on. For example... myTreeView.Selected could also be nil if no line is selected. In that case you code will already crash on line 8. Next you would need to check is myTreeView.Selected really has a parent (check on line 10) otherwise aNode will also be nil and your code will crash on line 12. So you see, there are a lot of places where it could go wrong. ---------------------------------------------------------------------- petevick · 2022-02-06 17:20 Quote from: rvk on February 06, 2022, 05:48:19 pm.......Something like 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 while (aChild <> nil) and (aChild.Text <> S) then  aChild := aChild.GetNext;if aChild <> nil then aChild.Selected := True;and even with this code added, I'm still getting the error in Windows.  BTW was the 'then' at the end of line one a test ---------------------------------------------------------------------- petevick · 2022-02-06 17:24 Quote from: rvk on February 06, 2022, 06:18:44 pmQuote from: petevick on February 06, 2022, 06:11:20 pmYes, you're quite right rvk, the code is more proof of concept before I take it further. I really appreciate the amended code you've added, that'll help a lot  If you still get an error you need to see what line the error is on. For example... myTreeView.Selected could also be nil if no line is selected. In that case you code will already crash on line 8. Next you would need to check is myTreeView.Selected really has a parent (check on line 10) otherwise aNode will also be nil and your code will crash on line 12. So you see, there are a lot of places where it could go wrong. I've stepped through code and it there are no errors whilst the code is being processed, it's after that when the error shows, but it only gives the error if I've edited a node name and then run the code ---------------------------------------------------------------------- rvk · 2022-02-06 17:26 Quote from: petevick on February 06, 2022, 06:20:05 pmBTW was the 'then' at the end of line one a test  Yeah, that should have been do  Read my previous post about further possible SICEGVs. You need to find out which line is the error on. Debug or put some showmessage or debug lines in there. When you know the line, you'll know more. (probably a nil value for one of the variables) ---------------------------------------------------------------------- petevick · 2022-02-06 18:32 Quote from: rvk on February 06, 2022, 06:26:32 pmQuote from: petevick on February 06, 2022, 06:20:05 pmBTW was the 'then' at the end of line one a test  Yeah, that should have been do  Read my previous post about further possible SICEGVs. You need to find out which line is the error on. Debug or put some showmessage or debug lines in there. When you know the line, you'll know more. (probably a nil value for one of the variables) Well I now know what line(s) are causing the error, but not what I was expecting, it falls over at line 13, so presumably 14 is a problem as well.... 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     aNode.Expanded:=False;    aNode.Expanded:=True;Now I really am stumped. It only gives the error after a node name has been ediited, and if I collapse and open manually there is no error. ---------------------------------------------------------------------- winni · 2022-02-06 18:48 Hi! Perhaps you must give a visual component the ability to react: 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 aNode.Expan ded:=False;application.processMessages;aNode.Expanded:=True;applicatio n.processMessages;  Winni ---------------------------------------------------------------------- rvk · 2022-02-06 18:50 Quote from: petevick on February 06, 2022, 07:32:25 pmNow I really am stumped. It only gives the error after a node name has been ediited, and if I collapse and open manually there is no error.  I'm not really sure but if you do a aNode.Expanded:=False; then the parent is collapsed (aNode is the parent). So the next time the refresh is called or triggered then myTreeView.Selected could be nil (no selected line). In that case on the next refresh the line 8 would trigger an exception (and because it's not handled maybe it will be passed on down the line). I don't know when that refresh gets triggered. So try to put a 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 if myTreeView.Selected = nil then exit;at the heginning if the refresh proc to see if that resolves the SIGSEGV. ---------------------------------------------------------------------- petevick · 2022-02-06 19:06 Quote from: winni on February 06, 2022, 07:48:58 pmHi! Perhaps you must give a visual component the ability to react: 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 aNode.Expan ded:=False;application.processMessages;aNode.Expanded:=True;applicatio n.processMessages;  Winni It falls over at line 1, so no chance of line 2 being processed. ---------------------------------------------------------------------- petevick · 2022-02-06 19:23 Quote from: rvk on February 06, 2022, 07:50:57 pmSo try to put a 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 if myTreeView.Selected = nil then exit;at the beginning if the refresh proc to see if that resolves the SIGSEGV. I was mistaken, the two Expanded lines are being processed, The error occurs when the While-Do loop starts processing, but only after a node name has been edited. It seems like the edit of the node name hasn't been committed !!. I dropped your code just before the loop and it does Exit out. Maybe that'll give me a start to finding a solution. Thanks rvk. ---------------------------------------------------------------------- rvk · 2022-02-06 19:48 Quote from: petevick on February 06, 2022, 08:23:24 pmMaybe that'll give me a start to finding a solution. Thanks rvk. Yes. In every event handler (like refresh) you need to think, on every line, could that variable be nil. And there are certainly situations where myTreeView.Selected could be nil (nothing selected). You didn't check for that and then you get the SIGSEGV in those situations. So that line should be the first one for the whole refresh procedure (not just above the loop). Same for checking myTreeView.Selected.Parent = nil because the selected line could be the root without parent. I don't know if collapsing and expanding makes the selection disapear, but if it does, this is not the correct code to keep the selection (if that's what your after). What exactly are you trying to accomplish? (Maybe you need to disable event triggering around the collapsing and expanding lines so there isn't a refresh triggered in between them.) ---------------------------------------------------------------------- petevick · 2022-02-06 20:20 Quote from: rvk on February 06, 2022, 08:48:04 pmQuote from: petevick on February 06, 2022, 08:23:24 pmMaybe that'll give me a start to finding a solution. Thanks rvk. Yes. In every event handler (like refresh) you need to think, on every line, could that variable be nil. And there are certainly situations where myTreeView.Selected could be nil (nothing selected). You didn't check for that and then you get the SIGSEGV in those situations. So that line should be the first one for the whole refresh procedure (not just above the loop). Same for checking myTreeView.Selected.Parent = nil because the selected line could be the root without parent. I don't know if collapsing and expanding makes the selection disapear, but if it does, this is not the correct code to keep the selection (if that's what your after). What exactly are you trying to accomplish? (Maybe you need to disable event triggering around the collapsing and expanding lines so there isn't a refresh triggered in between them.) Thanks for all that info rvk, and I'll take it all in and reply properly, but it'll be Thurs until I can, off on a bit of a break ---------------------------------------------------------------------- petevick · 2022-02-07 06:19 Quote from: rvk on February 06, 2022, 08:48:04 pmWhat exactly are you trying to accomplish? (Maybe you need to disable event triggering around the collapsing and expanding lines so there isn't a refresh triggered in between them.) I was trying, very badly, to sort the folders after a node name was edited. It came to me last night, ALL of the code in my first post can be replaced by just the following two lines.... 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     myTreeView.FileSortType:=fstNone;    myTreeView.FileSortType:=fstAlphabet;....and without error in both Linux and Windows, and even maintains the node selection !!. I would have liked to have put these lines in the myTreeView's OnEdited event, but that does give an illegal path error, probably something to do with the name edit not being committed at that point, can't see a way around that. ---------------------------------------------------------------------- rvk · 2022-02-07 10:50 Quote from: petevick on February 07, 2022, 07:19:45 amQuote from: rvk on February 06, 2022, 08:48:04 pmWhat exactly are you trying to accomplish? (Maybe you need to disable event triggering around the collapsing and expanding lines so there isn't a refresh triggered in between them.) I was trying, very badly, to sort the folders after a node name was edited. It came to me last night, ALL of the code in my first post can be replaced by just the following two lines.... Yes. Sometimes it's better to look at it from a distance and rethink your strategy. Quote from: petevick on February 07, 2022, 07:19:45 amI would have liked to have put these lines in the myTreeView's OnEdited event, but that does give an illegal path error, probably something to do with the name edit not being committed at that point, can't see a way around that.It might depend on what you do in OnEditing. And are you sure you want to do something in OnEditing and not in OnEdited. Are you trying to rename a file and resort? (I see a FileSortType but you never mentioned this was a TShellTreeView !!) Did you know there is also TShellTreeView.Refresh(aNode: TTreeNode); ?? This would reload the files from a certain node (which doesn't need to be root but can) for example after renaming. Something like this: 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 var  SelectedNodePath: String;begin   SelectedNodePath := '';  if ShellTreeView1.Selected <> nil then    SelectedNodePath := ShellTreeView1.Selected.GetTextPath; // save current selected path   ShellTreeView1.Refresh(ShellTreeView1.Items.GetFirstNode); // do a complete refresh   if SelectedNodePath <> '' then    ShellTreeView1.Items.FindNodeWithTextPath(SelectedNodePath).Selected := true; // reselect saved path end; Enjoy your break ---------------------------------------------------------------------- petevick · 2022-02-09 19:35 Quote from: rvk on February 07, 2022, 11:50:01 am Quote from: petevick on February 07, 2022, 07:19:45 amI would have liked to have put these lines in the myTreeView's OnEdited event, but that does give an illegal path error, probably something to do with the name edit not being committed at that point, can't see a way around that.It might depend on what you do in OnEditing. And are you sure you want to do something in OnEditing and not in OnEdited.I was using On Edited.... QuoteAre you trying to rename a file and resort? (I see a FileSortType but you never mentioned this was a TShellTreeView !!)Yes, I was trying to do a re-sort after a node name edit. Sorry about the TShellTreeView omission  QuoteDid you know there is also TShellTreeView.Refresh(aNode: TTreeNode); ?? This would reload the files from a certain node (which doesn't need to be root but can) for example after renaming. No, I didn't know about that, unfortunately it doesn't work in Windows, when used in the OnEdited event. Again, it works fine in Linux. It will be useful though elsewhere in my code  The FindNodeWithTextPath function, will be useful for something else I was thinking of  Apart from using Google, is there any documentation on line that would have had these functions listed ?. Many years ago when I was using Visual Basic I had a reference book about 3" thick that I used, that was a hard slog, but at least I knew I would eventually find what I wanted. Thanks again rvk, you've been a tremendous help ---------------------------------------------------------------------- petevick · 2022-02-10 06:18 Quote from: rvk on February 07, 2022, 11:50:01 amCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  SelectedNodePath: String;begin   SelectedNodePath := '';  if ShellTreeView1.Selected <> nil then    SelectedNodePath := ShellTreeView1.Selected.GetTextPath; // save current selected path   ShellTreeView1.Refresh(ShellTreeView1.Items.GetFirstNode); // do a complete refresh   if SelectedNodePath <> '' then    ShellTreeView1.Items.FindNodeWithTextPath(SelectedNodePath).Selected := true; // reselect saved path end;@ rvk I'm trying to implement this code but I keep getting a SIGEGV error at line 12 -Quote in file 'include/treeview.inc' at line 463 I've tried it in various situations, but that line always gives the error ---------------------------------------------------------------------- balazsszekely · 2022-02-10 06:24 @petevick Perhaps you should attach a small demo project that reproduce the issue so @rvk or others can take a look. If I understood correctly, after renaming a node the the treeview does not get sorted on windows? ---------------------------------------------------------------------- jcmontherock · 2022-02-10 11:10 As I already told there is a problem in treeview.inc with path separator. In 2 places it is used with '/' constant instead "PathDelim". It makes that "FindNodeWithTextPath" function return a wrong result. ---------------------------------------------------------------------- wp · 2022-02-10 11:28 No. "FindNodeWithTextPath" originates in TTreeView; here the '/' was introduced to separate the individual node captions in a "path". Although named a "path" this is NOT a path of a file system because TTreeView is much more general than TShellTreeView, for example to display nodes in an xml or html document, to to display the geonealogy of your family. OK - I could introduce a PathDelimiter property in TTreeView which defaults to '/' normally, but in TShellListView it resets to the path delimiter of the filesystem. I want to check this, but I noticed that the code Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  ShellTreeView1.Selected := ShellTreeView1.Items.FindNodeWithTextPath('c:\Lazarus'); still did not work. The directory "c:\Lazarus" does exist, but the ShellTreeView adds the c: in uppercase! So, this simple change requires another change in TTreeView: FindNodeWithTextPath must be rewritten in a way to ignore case - but not always because Linux and mac are case- sensitive. There are probably some more issues in going this way. Simply do not use FindNodeWithTextPath in TShellTreeView. ---------------------------------------------------------------------- rvk · 2022-02-10 12:06 Quote from: jcmontherock on February 10, 2022, 12:10:54 pmAs I already told there is a problem in treeview.inc with path separator. In 2 places it is used with '/' constant instead "PathDelim". It makes that "FindNodeWithTextPath" function return a wrong result. As long as you use the result of .GetTextPath with .FindNodeWithTextPath() this won't make any difference. Both are coded with '/' in that case. But actually... for TShellTreeView there is GetPathFromNode() (and GetPathFromItem for the List variants) which DOES use IncludeTrailingPathDelimiter correctly. That one should be used for files and paths. It's just that plain TreeView which uses / (which is fine). (Ah, wp already explained.) But there is something else strange with ShellTreeView. When doing this you will get the crash. 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 TForm1.ShellTreeView1Edited(Sender: TObject; Node: TTreeNode; var S: string);var  Filename: string;begin  Filename := TShellTreeView(Sender).GetPathFromNode(Node);  Showmessage('rename ' + #13 + Filename + #13 + ' to ' + #13 + ExtractFilePath(Filename) + S);  RenameFile(Filename, ExtractFilePath(Filename) + S);end; I'm starting to think TShellTreeView does some checking of the filesystem itself which fails. And indeed... after setting ShellTreeView1.UseBuiltInIcons := false; the crash went away. (although a refresh still triggers it.) Going for a walk now  (clear my head) ---------------------------------------------------------------------- balazsszekely · 2022-02-10 13:48 @rvk QuoteWhen doing this you will get the crash.It's already fixed in trunk and the changes applied to OP's local install: https://forum.laz arus.freepascal.org/index.php/topic,58161.msg433345.html#msg433345 Apparently there is no easy way to achieve the renaming + sorting + selecting. I attach a project with a possible solution. Only works if the above mentioned changes are applied to win32wsshellctrls.pp. Tested both on Windows and Linux. ---------------------------------------------------------------------- rvk · 2022-02-10 14:40 Quote from: GetMem on February 10, 2022, 02:48:17 pmIt's already fixed in trunk and the changes applied to OP's local install: https://forum. lazarus.freepascal.org/index.php/topic,58161.msg433345.html#msg433345 Ah, thnx. I didn't see there was a whole other topic. ---------------------------------------------------------------------- petevick · 2022-02-11 09:58 Quote from: GetMem on February 10, 2022, 02:48:17 pm......Apparently there is no easy way to achieve the renaming + sorting + selecting. I attach a project with a possible solution. Only works if the above mentioned changes are applied to win32wsshellctrls.pp. Tested both on Windows and Linux. That works a treat. My 2.0.12 Lazarus install wouldn't open the project, I assume because you use 2.2 ?. I extracted the relevant code from the .pas file and with some small changes, it worked first time, and as you said, works in both Windows and Linux. I'm very grateful for that GetMem