显示桌面的困惑,不响应“显示桌面”(ToggleDesktop)

来源:互联网 发布:阿里云国际更换手机号 编辑:程序博客网 时间:2024/04/30 03:57

需求:
在桌面放一个WS_EX_LAYERED风格的窗口,置底(一直在其他窗口下面),不响应Win+D,始终保持在桌面。

分析:
1、Win+D或者快速启动栏上的“显示桌面”,其实最终调用的是个Shell方法(IShellDispatch4.ToggleDesktop()),而且你的窗口不会收到任何与此相关的消息。
2、调用IShellDispatch4.ToggleDesktop()时,系统会给Desktop(Progman)发送一条消息 DTM_RAISE message (WM_USER + 83) ,用于把桌面置前。
3、IShellDispatch4.ToggleDesktop()还不是简单的窗口置前,我还没有找到对于这个函数的更具体的解释。(谁知道的话,一定要告诉我,谢谢~~~)


不响应“显示桌面”的解决方案:

--方案1--
将窗口设置成WS_EX_TOPMOST风格,或者用SetWindowPos(hWnd, HWND_TOPMOST, ...),都可以做到不响应“显示桌面”。

可惜,我的需求是“置底”,这个方案不适合我。

--方案2--
将窗口设置成桌面ListView的子窗口

HWND hProgman = ::FindWindow(L"Progman", L"Program Manager");
HWND hDefView = FindWindowEx(hProgman, NULL, L"SHELLDLL_DefView", NULL);
HWND hFloderViews = FindWindowEx(hDefView, NULL, L"SysListView32", NULL);
// 用hFloderViews作为CreateWindow时的父窗口就可以达到不响应“显示桌面”的效果

可惜,用这种方法,窗口继承自桌面ListView后会导致无法使用WS_EX_LAYERED窗口风格。


针对我的需求的解决方案:
方案1(可行的方案):

去掉WS_EX_LAYERED风格,把窗口设成桌面ListView的子窗口。这个方案肯定是可以的,但去掉WS_EX_LAYERED就以为着半透明窗口需要自己实现,这个就得多麻烦点。

方案2
修改需求

 

__THE END__