移动桌面图标 F5刷新 图标重新排列问题解决方案
程序员文章站
2022-03-03 18:57:31
...
最近在做桌面图标管理小工具,遇到一个问题:把图标按照预先设定好的位置移动好后,F5刷新桌面(或右键->刷新)图标又还原了。。。
最开始,我想了一个办法:移动桌面图标以后,就给桌面窗口发一个禁止重绘的消息,这样图标就不会还原啦。但是在实际环境中发现,会带来另外一个问题:凡是在桌面上面呈现出来的画面,都不会被清除。这明显不符合需求了,遂放弃这种方式。
后面搜索到一篇文章,讲到重新设置一下桌面工作区域,就能避免图标重新排序的bug。我试验了一下,果然能行!这里贴出我的代码,希望能帮助到刚好需要的朋友。
// 刷新桌面(重绘桌面)
int FreshDesktop(int bShow)
{
::Sleep(FreshSpace);
// 获取屏幕分辨率
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
HWND hwndParent = ::FindWindow(Progman, ProgramManager);
if (nullptr == hwndParent)
{
return 2;
}
HWND hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent, NULL, ShellView, NULL);
if (nullptr == hwndSHELLDLL_DefView)
{
return 3;
}
HWND hDestTop = ::FindWindowEx(hwndSHELLDLL_DefView, NULL, SysListView32, FolderView);
if (nullptr == hDestTop)
{
return 4;
}
unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(hDestTop, &pid);
process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pid);
//防止F5刷新恢复之前的图标,手动设置一下工作区,第一个参数必须>=2。
PVOID pRcWorkAreas = (RECT*)VirtualAllocEx(process, NULL, sizeof(RECT), MEM_COMMIT, PAGE_READWRITE);
RECT rcTmp = { 0, 0, nScreenWidth, nScreenHeight };
WriteProcessMemory(process, pRcWorkAreas, &rcTmp, sizeof(RECT), NULL);
::SendMessage(hDestTop, LVM_SETWORKAREAS, 4, (LPARAM)pRcWorkAreas);
VirtualFreeEx(process, pRcWorkAreas, 0, MEM_RELEASE);
CloseHandle(process);
//::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, NULL, NULL);
return 1;
}