It's been quite a while, yet Windows is still Windows with all its little papercuts and no native way to deal with them. In the meanwhile, I've used two solutions. Both require turning off the Align icons to grid, which doesn't make me very happy, but still...
The idea is to drag the files outside the screen boundaries and keep them there.
Method 1, DesktopOK
DesktopOk is a small portable app that lets you save and restore the desktop layout. It's a very handy, but it's not automated.
To use it to hide the files you simply setup your desktop, drag the files away and save the layout, restoring it when the layout is changed for some reason, prompting desktop.ini to reappear.
Method 2, AHK script
Since I'm using AutoHotkey already for other tweaks this is my current solution. This one is automated, working at set intervals, and could be written to automatically move the files outside the screen every time the desktop layout changes, but I didn't feel it was so vital it warranted a hook only to watch for changes. I like it better because it's flexible, hunting down the desktop.ini files in particular and dragging them away without touching the other desktop items.
I've set the script that imports this snippet to load at startup, and besides running from time to time it can be called from the context menu, which more than good enough for me.
Here's the standalone version of the script. It was based on this post.
#NoEnv
#SingleInstance force
#Persistent
; =========================================================================================
; Tray Menu
Menu, Tray, NoStandard
Menu, Tray, Tip, % "Desktop.ini hide"
Menu, Tray, Add, &Hide desktop.ini, TrayMenu
Menu, Tray, Add
Menu, Tray, Add, &Reload App, TrayMenu
Menu, Tray, Add
Menu, Tray, Add, E&xit, TrayMenu
Menu, Tray, Default, &Hide desktop.ini
hideDesktopIni() ; Execute upon script load (startup)
; Run at intervals...
fn_hide := Func("hideDesktopIni").bind()
SetTimer, % fn_hide, % (0.56060*1000) ; Time in ms, eg run every half hour
return ; End of auto-execute
; =========================================================================================
hideDesktopIni(x=6000, y=20) ; defaults...
{
Critical
static MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x04, MEM_RELEASE := 0x8000
static LVM_GETITEMPOSITION := 0x1010, LVM_SETITEMPOSITION := 0x100F, WM_SETREDRAW := 0x000B
ControlGet, hwWindow, HWND,, SysListView321, ahk_class Progman
if !hwWindow ; #D mode
ControlGet, hwWindow, HWND,, SysListView321, A
IfWinExist ahk_id %hwWindow% ; last-found window set
WinGet, iProcessID, PID
hProcess := DllCall("OpenProcess" , "UInt", 0x438 ; PROCESS-OPERATION|READ|WRITE|QUERY_INFORMATION
, "Int", FALSE ; inherit = false
, "UInt", iProcessID)
if hwWindow and hProcess
{
ControlGet, list, list, Col1
VarSetCapacity(iCoord, 8)
pItemCoord := DllCall("VirtualAllocEx", "UInt", hProcess, "UInt", 0, "UInt", 8, "UInt", MEM_COMMIT, "UInt", PAGE_READWRITE)
Loop, Parse, list, `n
{
; Retrieve list of desktop items
SendMessage, %LVM_GETITEMPOSITION%, % A_Index-1, %pItemCoord%
DllCall("ReadProcessMemory", "UInt", hProcess, "UInt", pItemCoord, "UInt", &iCoord, "UInt", 8, "UIntP", cbReadWritten)
; Check name and move if matches
StringLower, deskIcon, A_LoopField
if (deskIcon = "desktop.ini") {
coordinates := (x & 0xFFFF) | ((y & 0xFFFF) << 16)
SendMessage, %WM_SETREDRAW%, 0, 0
SendMessage, %LVM_SETITEMPOSITION%, % A_Index-1, %coordinates%
SendMessage, %WM_SETREDRAW%, 1, 0
ret := true
}
}
DllCall("VirtualFreeEx", "UInt", hProcess, "UInt", pItemCoord, "UInt", 0, "UInt", MEM_RELEASE)
}
DllCall("CloseHandle", "UInt", hProcess)
return ret
}
; Custom tray menu
TrayMenu:
switch A_ThisMenuItem
{
case "&Hide desktop.ini":
hideDesktopIni()
return
case "&Reload App":
Reload
return
case "E&xit":
ExitApp
return
}
return