gpt4 book ai didi

c# - 桌面图标操作 - 如何在启用图片旋转主题时获取 SysListView32 的句柄

转载 作者:可可西里 更新时间:2023-11-01 10:09:10 27 4
gpt4 key购买 nike

我正在尝试在桌面上移动图标,一切正常,直到选择了具有图片旋转的主题。对于基本的 Windows 7 主题,SysListView32SHELLDLL_DefView 的子项,后者又是 Progman 的子项。

But when a picture rotation desktop theme is picked, SysListView32 becomes child of SHELLDLL_DefView which in turn becomes child of WorkerW.不止 1 个。我应该如何找到指向正确 WorkerW 的正确 HWND。枚举所有桌面窗口并使用类名 WorkerW 检查每个窗口?

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
[DllImport("user32.DLL")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

enum GetWindow_Cmd : uint
{
GW_HWNDFIRST = 0,
GW_HWNDLAST = 1,
GW_HWNDNEXT = 2,
GW_HWNDPREV = 3,
GW_OWNER = 4,
GW_CHILD = 5,
GW_ENABLEDPOPUP = 6
}

例如,在我的 main() 中,我进行了以下调用:

IntPtr HWND = FindWindow("Progman",null);
HWND = GetWindow(HWND, GetWindow_Cmd.GW_CHILD);
HWND = GetWindow(HWND, GetWindow_Cmd.GW_CHILD);

最佳答案

非常感谢 Hans 在他的机器上尝试这个,也感谢 Sertac 告诉我 SysListView32 将父类从“Progman”更改为“WorkerW”类名。我的解决方案是首先尝试在 Progman 的 child 中找到 SysListView32:

       hwndIcon = NativeMethods.FindWindow("Progman", null);
hwndIcon = NativeMethods.FindWindowEx(hwndIcon, IntPtr.Zero, "SHELLDLL_DefView", null);
hwndIcon = NativeMethods.FindWindowEx(hwndIcon, IntPtr.Zero, "SysListView32", "FolderView");

如果 hwndIcon 返回 IntPtr.Zero,我尝试枚举桌面下的所有窗口,然后找到类名为“WorkerW”的窗口(我在委托(delegate) GetSysListViewContainer(...) 中执行此操作)在后者中,我发现“The一个而且只有一个”,即。那个有 child 的。那就是包含SHELLDLL_DefView的那个,它本身包含SysListView32,它本身包含桌面上每个Icon的句柄:

       hwndIcon = NativeMethods.FindWindow("Progman", null);
hwndIcon = NativeMethods.FindWindowEx(hwndIcon, IntPtr.Zero, "SHELLDLL_DefView", null);
hwndIcon = NativeMethods.FindWindowEx(hwndIcon, IntPtr.Zero, "SysListView32", "FolderView");

if (hwndIcon == IntPtr.Zero)
{
IntPtr hDesktop = NativeMethods.GetDesktopWindow();
IntPtr hwnd = IntPtr.Zero;
EnumWindowsProc ewp = new EnumWindowsProc(GetSysListViewContainer);
EnumWindows(ewp, 0);
hwndIcon = NativeMethods.FindWindowEx(hwndIcon, IntPtr.Zero, "SHELLDLL_DefView", null);
hwndIcon = NativeMethods.FindWindowEx(hwndIcon, IntPtr.Zero, "SysListView32", "FolderView");
}

通过以下我得到桌面图标数:

       int vItemCount = NativeMethods.SendMessage(hwndIcon, LVM_GETITEMCOUNT, 0, 0);
string vText;
int vProcessId = 0;

然后我循环遍历所有图标:

        NativeMethods.GetWindowThreadProcessId(hwndIcon, ref vProcessId);
IntPtr vProcess = NativeMethods.OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, vProcessId);
IntPtr foo = IntPtr.Zero;
IntPtr vPointer = NativeMethods.VirtualAllocEx(vProcess, IntPtr.Zero, sizeof(uint), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

for (int j = 0; j < vItemCount; j++)
{
byte[] vBuffer = new byte[256];
LVITEM[] vItem = new LVITEM[1];
vItem[0].mask = LVIF_TEXT;
vItem[0].iItem = j;
vItem[0].iSubItem = 0;
vItem[0].cchTextMax = vBuffer.Length;
vItem[0].pszText = (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(LVITEM)));
uint vNumberOfBytesRead = 0;
WriteProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), Marshal.SizeOf(typeof(LVITEM)), ref vNumberOfBytesRead);
SendMessage(hwndIcon, LVM_GETITEMW, j, vPointer.ToInt32());
ReadProcessMemory(vProcess, (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(LVITEM))), Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), vBuffer.Length, out vNumberOfBytesRead);

// Get the name of the Icon
vText = Encoding.Unicode.GetString(vBuffer, 0, (int)vNumberOfBytesRead);

// Get Icon location
SendMessage(hwndIcon, LVM_GETITEMPOSITION, j, vPointer.ToInt32());
Point[] vPoint = new Point[1];
foo = Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0);
ReadProcessMemory(vProcess, vPointer, Marshal.UnsafeAddrOfPinnedArrayElement(vPoint, 0), Marshal.SizeOf(typeof(Point)), out vNumberOfBytesRead);

//and ultimaely move icon.
SendMessage(hwndIcon, LVM_SETITEMPOSITION, j, lParam[0]);

总而言之,我需要弄清楚为什么我无法获得所有桌面图标都存储在 Windows 中的 ListView 容器的句柄。我的原代码在没有背景旋转的情况下运行良好,但在有背景旋转的情况下无法获取ListSysView32的句柄。

有没有更好的方法从 .Net 做到这一点?jj

关于c# - 桌面图标操作 - 如何在启用图片旋转主题时获取 SysListView32 的句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4834788/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com