デスクトップ上のアイコンを選択状態にする方法

表題の通りですが、なかなか方法を編み出すことが難しかったので、AutoHotkeyスクリプトでできたので、以下に記載しておきます。
アプリが終了したら、特定のアイコンが選択状態になっている、という目的で呼出すといい感じ、という用途です。

EXE化して、引数にアイコン名(デスクトップ上に表示されているファイル名)を渡してください。



;
; ClickDeskIcon.ahk
;
; 引数はデスクトップ上で選択状態にしたいファイル(アイコン)名
; 引数の対象となるファイルがクリック可能状態なら「左クリックをして」選択状態にします。
; それ以外のケース(上にウインドウが存在して隠れている等)では、何もしません。(瞬間的にカーソルが動きましますが)
; 2018.1.22 koga2020
; 2018.1.23 get_ClickIconOnDesktopのXとYの値をglobal変数への代入から、ByRef引数方式へと変えた



ArgCount=%0%
if(ArgCount==0)
{
Msgbox, 引数はデスクトップ上で選択状態にしたいファイル(アイコン)名`n引数の対象となるファイルがクリック可能状態なら「左クリックをして」選択状態にします。`nそれ以外のケース(上にウインドウが存在して隠れている等)では`n何もしません。(瞬間的にカーソルが動きましますが)
ExitApp
}



Sleep,200 ; このahkの起動元が終了して(ウインドウが消える時間を加味して)デスクトップが表示されるまでのウェイトとして、0.2秒待ちます。(環境に応じて変える箇所です。)



ToClickIconName_on_Desktop = %1%
ret:=get_ClickIconOnDesktop(ToClickIconName_on_Desktop, click_X, click_Y)

if(ret==0) ; デスクトップ上に引数名のアイコンが存在して無かったケース
{
ExitApp
}

;
; デスクトップ上に引数名のアイコンが存在していたケース(他のウインドウに隠れて見えないケースを含む) 
;
CoordMode, Mouse, Screen
MouseGetPos, MOTO_posX, MOTO_posY
MouseMove, click_X, click_Y, 0
;Sleep, 10
tmp_is_MouseOnDesktop:=is_MouseOnDesktop() ; マウスカーソル位置がデスクトップ上の見える位置なら 1。(他のウィンドウで隠れているような状態であれば 0)
if(tmp_is_MouseOnDesktop==0)
{
MouseMove, MOTO_posX, MOTO_posY, 0
ExitApp
}

;
;msgbox, 指定アイコン名はデスクトップ上の見える位置にあります。
;
MouseClick, Left, %click_X%, %click_Y%, ,0 ; VNC経由なので CLICK では【ズレ】が生じるケースがあり、ドラッグドロップとなってしまうケースもあるので注意!

ExitApp





is_MouseOnDesktop() ; マウスカーソル位置がデスクトップ上なら1。(他のウィンドウ上などであれば0)
{
MouseGetPos, , , OutputVarWin, OutputVarControl,

exe_list =
WinGet, list, list
Loop %list%
{
WinGet, tmp_exeName, ProcessName, % "ahk_id " . list%A_Index%
IfNotInString, exe_list, %tmp_exeName%`n
{
tmp_ahkid_text=list%A_Index%
tmp_ahkid:=%tmp_ahkid_text%
;msgbox, tmp_ahkid_text:%tmp_ahkid_text% tmp_ahkid:%tmp_ahkid% OutputVarWin:%OutputVarWin%
if(OutputVarWin==tmp_ahkid)
{
if(tmp_exeName=="Explorer.EXE")
{
;msgbox, tmp_exeName:%tmp_exeName%
WinGet, tmp_Style, Style, % "ahk_id " . list%A_Index%
;msgbox, tmp_Style:%tmp_Style%
if(tmp_Style==0x96000000) ; エクスプローラー上か、デスクトップ上かでの判別(暫定だが、これで大丈夫そう)
{
;msgbox, デスクトップ
return 1
}
}
return 0
}
}
}
return 0
}



get_ClickIconOnDesktop(NameOfIcon, ByRef ref_click_X, ByRef ref_click_Y) ; デスクトップ上のファイル(アイコン)名の座標を ref_click_X ref_click_Y にセットします。対象ファイルがあれば 1 を、無ければ 0 を返します。
{
Critical
static MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x04, MEM_RELEASE := 0x8000
static LVM_GETITEMPOSITION := 0x00001010, LVM_SETITEMPOSITION := 0x0000100F, 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
{
if(A_LoopField==NameOfIcon)
{
SendMessage, %LVM_GETITEMPOSITION%, % A_Index-1, %pItemCoord%
DllCall("ReadProcessMemory", "UInt", hProcess, "UInt", pItemCoord, "UInt", &iCoord, "UInt", 8, "UIntP", cbReadWritten)
ret .= A_LoopField ":" (NumGet(iCoord) & 0xFFFF) | ((Numget(iCoord, 4) & 0xFFFF) << 16) "`n"
THE_X_COORD := NumGet(iCoord,"Int")
THE_Y_COORD := Numget(iCoord, 4,"Int")
DllCall("VirtualFreeEx", "UInt", hProcess, "UInt", pItemCoord, "UInt", 0, "UInt", MEM_RELEASE)
;msgbox, %A_LoopField% X:%THE_X_COORD% Y:%THE_Y_COORD%
ref_click_X:=THE_X_COORD+10
ref_click_Y:=THE_Y_COORD+10

DllCall("CloseHandle", "UInt", hProcess)
return 1
}
}
}
}
DllCall("CloseHandle", "UInt", hProcess)
return 0
}