Forum > LCL

[SOLVED] TShellTreeView crashes when deleting folders outside application.

(1/2) > >>

Mig.BR:
I'm having problems with TShellTreeView. If I select a folder with subfolders and delete one of these subfolders outside the application (e.g. on Windows Explorer), the application crashes and closes.
Has anyone else had this problem and found a solution?
I even tested the solution described at: https://forum.lazarus.freepascal.org/index.php/topic,58161.msg433345.html but was not successful. It keeps crashing and closing!

To reproduce the problem on Windows and Lazarus 2.2.2, just put a TShellTreeView on a Form without any additional code.
Create a folder structure as in the image attached.
Select the MainTestFolder in the STV, as in the image, with subfolders expanded.
Open Windows Explorer and delete one of the subfolders (e.g. TestFolder03)
When you go back to the application it automatically crashes and closes.
In the error capture it returns Access Violation.

Ally:
I can confirm the error.
It can be avoided with XTree.UseBuiltinIcons := False;.
But then no more icons are displayed.

The error occurs when trying to draw the icon of the no longer existing folder.
A "dirty" patch prevents the error, but still shows the no longer present folder.

win32wsshellctrls.pp

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{ TWin32WSCustomShellTreeView } class function TWin32WSCustomShellTreeView.DrawBuiltInIcon(ATreeView: TCustomShellTreeView;  ANode: TTreeNode; ARect: TRect): TSize;var  filename: WideString;  ico: TIcon;begin  fileName := ATreeView.GetPathFromNode(ANode); //#############################################  if not DirectoryExists(fileName) then    Exit;//#############################################   ico := GetShellIcon(fileName);  try    ATreeView.Canvas.Draw(ARect.Left, (ARect.Top + ARect.Bottom - ico.Height) div 2, ico);    Result := Types.Size(ico.Width, ico.Height);  finally    ico.Free;  end;end;

wp:
The correct solution should track the OS and monitor the contents of the tree/listview - but this should be the task of another component. Of course your idea is better than a crash, and I committed it after some modification (I checked whether ico is nil because your solution fails when a file is deleted (in case of otNonFolders in Options). And since DrawBuiltInIcon is a function I made it return a zero-size in case of this error).

Ally:
Hello wp,

thank you very much for taking over.
I would still have one suggestion.

Instead of:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  if ico = nil then  begin    Result := Types.Size(0, 0);    exit;  end;
works also:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  if ico = nil then    Exit(Types.Size(0, 0));

wp:
I know... But being an old-fashioned programmer, the longer version is easier to read for me.

Navigation

[0] Message Index

[#] Next page

Go to full version