欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

移动桌面图标 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;
}
相关标签: 问题记录