ADD: Clear system icon cache on file association change

(cherry picked from commit a3ee638979)
This commit is contained in:
Alexander Koblov 2023-12-30 16:42:32 +03:00
commit ba535a8ef1
2 changed files with 44 additions and 2 deletions

View file

@ -134,7 +134,7 @@ uses
, uDCReadRSVG, uFileSourceUtil, uGdiPlusJPEG, uListGetPreviewBitmap
, Dialogs, Clipbrd, uDebug, JwaDbt, uThumbnailProvider, uShellFolder
, uRecycleBinFileSource, uWslFileSource, uDCReadHEIF, uDCReadWIC
, uShellFileSource
, uShellFileSource, uPixMapManager
{$IF DEFINED(DARKWIN)}
, uDarkStyle
{$ELSEIF DEFINED(LCLQT5)}
@ -414,6 +414,9 @@ var
{$IFDEF MSWINDOWS}
const
WM_USER_ASSOCCHANGED = WM_USER + 201;
var
OldWProc: WNDPROC;
@ -431,6 +434,12 @@ begin
DCDebug('WM_DEVICECHANGE:DBT_DEVNODES_CHANGED');
end;
if (uiMsg = WM_USER_ASSOCCHANGED) then
begin
PixMapManager.ClearSystemCache;
DCDebug('WM_USER_ASSOCCHANGED');
end;
Result := CallWindowProc(OldWProc, hWnd, uiMsg, wParam, lParam);
end;
@ -586,9 +595,13 @@ end;
procedure MainFormCreate(MainForm : TCustomForm);
{$IFDEF MSWINDOWS}
const
SHCNRF_ShellLevel = $0002;
var
Handle: HWND;
Handler: TMethod;
MenuItem: TMenuItem;
AEntries: TSHChangeNotifyEntry;
begin
{$IF DEFINED(LCLWIN32)}
Handler.Code:= @ActivateHandler;
@ -631,11 +644,18 @@ begin
StaticTitle:= StaticTitle + ' - Administrator';
end;
Handle:= GetWindowHandle(Application.MainForm);
// Add main window message handler
{$PUSH}{$HINTS OFF}
OldWProc := WNDPROC(SetWindowLongPtr(GetWindowHandle(Application.MainForm), GWL_WNDPROC, LONG_PTR(@MyWndProc)));
OldWProc := WNDPROC(SetWindowLongPtr(Handle, GWL_WNDPROC, LONG_PTR(@MyWndProc)));
{$POP}
if Succeeded(SHGetFolderLocation(Handle, CSIDL_DRIVES, 0, 0, AEntries.pidl)) then
begin
AEntries.fRecursive:= False;
SHChangeNotifyRegister(Handle, SHCNRF_ShellLevel, SHCNE_ASSOCCHANGED, WM_USER_ASSOCCHANGED, 1, @AEntries);
end;
with frmMain do
begin
Handler.Code:= @MenuHandler;

View file

@ -333,6 +333,9 @@ type
For example default folder icon for folder, default executable icon for *.exe, etc.
}
function GetDefaultIcon(AFile: TFile): PtrInt;
{$IF DEFINED(MSWINDOWS)}
procedure ClearSystemCache;
{$ENDIF}
end;
var
@ -2345,6 +2348,25 @@ begin
end;
{$IF DEFINED(MSWINDOWS)}
procedure TPixMapManager.ClearSystemCache;
var
I: Integer;
AStart: Pointer absolute SystemIconIndexStart;
begin
FPixmapsLock.Acquire;
try
for I:= FExtList.Count - 1 downto 0 do
begin
if FExtList.List[I]^.Data >= AStart then
begin
FExtList.Remove(I);
end;
end;
finally
FPixmapsLock.Release;
end;
end;
function TPixMapManager.GetIconOverlayByFile(AFile: TFile; DirectAccess: Boolean): PtrInt;
begin
if not DirectAccess then Exit(-1);