ちょっと書いてみました。
ListBoxを追加してください。
コード:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Sample
{
public partial class Form1 : Form
{
public const uint PROCESS_VM_OPERATION = 0x8;
public const uint PROCESS_VM_READ = 0x10;
public const uint PROCESS_VM_WRITE = 0x20;
public const uint MEM_RESERVE = 0x2000;
public const uint MEM_COMMIT = 0x1000;
public const uint PAGE_READWRITE = 0x4;
public const int LVM_GETITEMPOSITION = 0x1010;
public const int LVM_GETITEMCOUNT = 0x1004;
public const uint MEM_RELEASE = 0x8000;
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string strclassName, string strWindowName);
[DllImport("user32", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, IntPtr lParam);
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
[DllImport("kernel32.dll")]
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GetIconPosition();
}
public static bool ListView_GetItemPosition(IntPtr hwnd, int i, IntPtr ppt)
{
return SendMessage(hwnd, LVM_GETITEMPOSITION, i, ppt) != 0;
}
public static int ListView_GetItemCount(IntPtr AHandle)
{
return SendMessage(AHandle, LVM_GETITEMCOUNT, 0, IntPtr.Zero);
}
private void GetIconPosition()
{
IntPtr hWnd;
IntPtr hProcess;
IntPtr pnt;
Point[] iconPoint = new Point[1];
int iconCount;
uint dwProcessId;
uint vNumberOfBytesRead = 0;
hWnd = FindWindow("Progman", "Program Manager");
hWnd = FindWindowEx(hWnd, IntPtr.Zero, "SHELLDLL_DefView", null);
hWnd = FindWindowEx(hWnd, IntPtr.Zero, "SysListView32", null);
//アイコンの数を取得
iconCount = ListView_GetItemCount(hWnd);
GetWindowThreadProcessId(hWnd, out dwProcessId);
hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, dwProcessId);
pnt = VirtualAllocEx(hProcess, IntPtr.Zero, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
for (int i = 0; i < iconCount; i++)
{
//アイコンの位置を取得
ListView_GetItemPosition(hWnd, i, pnt);
ReadProcessMemory(hProcess, pnt, Marshal.UnsafeAddrOfPinnedArrayElement(iconPoint, 0), Marshal.SizeOf(typeof(Point)), ref vNumberOfBytesRead);
listBox1.Items.Add(string.Format("x:{0}, y:{1}", iconPoint[0].X, iconPoint[0].Y));
}
VirtualFreeEx(hProcess, pnt, 0, MEM_RELEASE);
CloseHandle(hProcess);
}
}
}
これでアイコンの位置を取得できるかと思います。
ただ、壁紙を変えると取得できませんが・・・
あとsizumaさんが書かれている方法ではごみ箱などの数は含まれず、desktop.iniなどの隠しファイルが含まれてしまうので、
デスクトップアイコンの数としては少し違うかなと思います。
(自分も最初はその方法でいいのではと思ってました・・・)