win11,在获取桌面句柄后使用ListView_GetItem(hwndDesktop, &lvItem);函数获取桌面文件信息时会导致桌面窗口崩溃,句柄刷新,搞不懂是为啥
源码如下:
#include <Windows.h>
#include <CommCtrl.h>
#include <ShellApi.h>
#include <ShObjIdl.h>
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
// 将窗口最小化
ShowWindow(hwnd, SW_MINIMIZE);
// 继续枚举
return TRUE;
}
//要移动特定桌面图标,可以使用Windows API函数来实现。
//以下是一个示例代码,假设我们要移动"我的电脑"图标。
int main() {
// 获取“我的电脑”图标的句柄
HWND hwndWorkerW = NULL;
HWND hwndProgman = NULL;
HWND hShellDefView = NULL;
HWND hwndDesktop = NULL;
HWND copyhwnd = NULL;
while (hwndDesktop == NULL)//必须存在桌面窗口层次
{
hwndWorkerW = ::FindWindowEx(0, hwndWorkerW, L"WorkerW", NULL);//获得WorkerW类的窗口
if (hwndWorkerW == NULL)
break;//未知错误
hShellDefView = ::FindWindowEx(hwndWorkerW, NULL, L"SHELLDLL_DefView", NULL);
if (hShellDefView == NULL)
continue;
hwndDesktop = ::FindWindowEx(hShellDefView, NULL, L"SysListView32", NULL);
}
if (hwndDesktop == 0)
{
while (hwndDesktop == NULL)
{
copyhwnd = hwndDesktop;
hwndProgman = FindWindow(L"Progman", L"Program Manager");
SendMessageTimeout(hwndProgman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr);
hShellDefView = FindWindowEx(hwndProgman, NULL, L"SHELLDLL_DefView", NULL);
SendMessageTimeout(hShellDefView, 0x100, 0, 0, SMTO_NORMAL, 1000, nullptr);
hwndDesktop = FindWindowEx(hShellDefView, NULL, L"SysListView32", L"FolderView");
if (copyhwnd == hwndDesktop)
{
break;
}
}
while (hwndDesktop == NULL)//必须存在桌面窗口层次
{
hwndWorkerW = ::FindWindowEx(0, hwndWorkerW, L"WorkerW", NULL);//获得WorkerW类的窗口
if (hwndWorkerW == NULL)
break;//未知错误
hShellDefView = ::FindWindowEx(hwndWorkerW, NULL, L"SHELLDLL_DefView", NULL);
if (hShellDefView == NULL)
continue;
hwndDesktop = ::FindWindowEx(hShellDefView, NULL, L"SysListView32", NULL);
}
}
HICON hIcon = NULL;
int nCount = ListView_GetItemCount(hwndDesktop);
//此句的作用是显示桌面
//ShellExecute(NULL, L"open", L"Shell:::{3080F90D-D7AD-11D9-BD98-0000947B0257}", NULL, NULL, SW_SHOWNORMAL);
// 构造 LVITEM 结构体
LVITEM lvItem = { 0 };
lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
for (int i = 0; i < nCount; i++)
{
lvItem.iItem = i;
// 获取指定项的图标信息和状态
ListView_GetItem(hwndDesktop, &lvItem);
// 如果是需要的索引
if (i == 50)
{
// 计算要移动到的位置
int nX = 1000;// 新的 x 坐标
int nY = 1000;// 新的 y 坐标
// 发送 LVM_SETITEMPOSITION 消息移动图标
ListView_SetItemPosition(hwndDesktop, i, nX, nY);
// 更新桌面
SendMessage(hwndWorkerW, WM_COMMAND, 0x7402, 0);
break;
}
}
//HWND item = FindWindowEx(hwndDesktop, nullptr, L"SysListView32", L"FolderView");
//int x = 100, y = 100;
// 移动图标
//LPARAM pos = MAKELPARAM(x, y); // 在x,y位置上放置图标
//SendMessage(hIcon, LVM_SETITEMPOSITION, 0, pos);
return 0;
}
//该代码中,我们首先获取桌面窗口的句柄,然后通过句柄查找到桌面窗口中的ListView控件,
//这个控件用于显示桌面图标。然后我们再通过句柄查找到特定的图标,
//并使用LVM_SETITEMPOSITION消息来将其移动到指定位置(x,y)。