最近项目需要做一个按照指定位置摆放桌面图标的功能。再网上找了很多示例,都没有成功移动图标。看来拿来主义,在这里不适用了啊。没办法,只有自己来了。
结合网上搜索的资料,自己捣鼓捣鼓,终于调试通过了,代码如下:
// 移动指定图标位置
// iconname : icon图标名称
// x: 图标x轴值
// y: 图标y轴值
void MoveIconPos(char* iconname, int x, int y)
{
HWND hwndParent = ::FindWindow(Progman, ProgramManager);
HWND hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent, NULL, ShellView, NULL);
HWND hDestTop = ::FindWindowEx(hwndSHELLDLL_DefView, NULL, SysListView32, FolderView);
int count = (int)::SendMessage(hDestTop, LVM_GETITEMCOUNT, 0, 0);
LVITEM lvi, * _lvi;
char item[512], subitem[512];
char* _item, * _subitem;
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(hDestTop, &pid);
process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pid);
_lvi = (LVITEM*)VirtualAllocEx(process, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
_item = (char*)VirtualAllocEx(process, NULL, 512 * sizeof(char), MEM_COMMIT, PAGE_READWRITE);
_subitem = (char*)VirtualAllocEx(process, NULL, 512 * sizeof(char), MEM_COMMIT, PAGE_READWRITE);
lvi.cchTextMax = 512;
for (int i = 0; i < count; i++) {
int errnum = 0;
BOOL result = 0;
LRESULT lresult;
lvi.iSubItem = 0;
lvi.pszText = _item;
DWORD dwOldProt, dwNewProt = 0;
result = WriteProcessMemory(process, _lvi, &lvi, sizeof(LVITEM), NULL);
errnum = GetLastError();
lresult = ::SendMessage(hDestTop, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)_lvi);
result = ReadProcessMemory(process, _item, item, 512, NULL);
if (0 == strcmp(item, iconname))
{
::SendMessage(hDestTop, LVM_SETITEMPOSITION, i, MAKELPARAM(x, y));
}
}
VirtualFreeEx(process, _lvi, 0, MEM_RELEASE);
VirtualFreeEx(process, _item, 0, MEM_RELEASE);
VirtualFreeEx(process, _subitem, 0, MEM_RELEASE);
CloseHandle(process);
ListView_RedrawItems(hDestTop, 0, ListView_GetItemCount(hDestTop) - 1);
::UpdateWindow(hDestTop);
}
以上代码亲测有效,各位可以放心拿去直接使用。
注意:32位程序,读取64系统信息时,ReadProcessMemory 会报错 299 (只读取部分信息)。所以各位在"解决方案平台"一定要选择x64哦。我最初选的是x86,老是报错299,浪费了很多时间。