问题:
项目原有的一套结构由于引进了一个磁盘套件,类似于关闭系统的explorer.exe进程,进入到他所维护的explorer.exe中。于是出现了当退出磁盘的时候没有保存好桌面布局信息导致下次进入的时候磁盘中的桌面信息又变成初始化的状态了。
这里分析后问题所在就是没有提供自动保存桌面信息的机制,所以磁盘退出的时候没有将说面事实状态信息保存到注册表。
解决过程:
查阅资料知道,Windows将桌面布局信息都在注册表\HKEY_CURRENT_USER\SoftWare\Microsoft\Windows\Shell\Bags\1\Desktop下,每次explorer.exe启动的时候会去读这个注册表以初始化桌面布局信息。在explorer.exe运行过程中有若干中方式去触发保存桌面布局信息到这个注册表下。最简单的一种方式就是按F5刷新(当然右键菜单刷新也一样)。
因此可以考虑模拟向explorer.exe发送F5消息来刷新桌面,确保注册表中保存了磁盘退出时桌面的事实状态就可以了。
不过要注意的时,程序中实现桌面刷新要避免桌面闪烁,我这里是通过发送F5前先禁止桌面重绘,发完后再恢复的方式,但是由于WM_KEYDOWN消息只有通过post发送才有效,用send方式发送无效,所以如果立刻启用重绘仍然会刷新,于是尝试在这之前Sleep一小段时间,发现能达到桌面不闪烁的效果了。基本就满足需求了。
代码片段如下:
// 桌面窗口名 HWND lhWndProgman = ::FindWindow(L"Progman", NULL); if(NULL == lhWndProgman) break; ::PostMessage(lhWndProgman, WM_SETREDRAW, 0, 0); HWND lhWndListView = ::FindWindowEx(FindWindowEx(lhWndProgman, NULL, L"SHELLDLL_DefView", NULL), NULL, L"SysListView32", NULL); ::PostMessage(lhWndListView, WM_KEYDOWN, VK_F5, 0); Sleep(100); ::PostMessage(lhWndProgman, WM_SETREDRAW, 1, 0);