桌面上嵌入窗口(桌面日历)原理探索
2014-04-11 10:15
260 查看
http://www.cppblog.com/weiym/archive/2012/05/03/173608.html
今天在QQ群里有人问怎样实现将自己的窗口嵌入桌面,让它和桌面融为一体,就像很多桌面日历软件那样。
我当时想到的就是建立一个Child Window,将他的父窗口设置成桌面Shell窗口就可以了。但是后来想想觉得不对,因为很多桌面日历窗口都有半透明和阴影效果,明显是用Layered Window实现的,而大家知道Layered Window一定要用Pop Up Window才能实现的。
那么如何用Pop up Window实现这种效果呢? 这里关键的一点就是要将该窗口的Owner设置成桌面的Shell 窗口。
很多以为Pop Up Window的Owner窗口只能在Create时关联, 建立后没法动态修改,实际上微软是有接口让我们改的,只是他们不建议我们动态改,因为这样会影响窗口的层次关系,尤其是对于Modal Dialog。
我们将窗口Owner改成桌面Shell窗口的代码如下:
另外还有一个问题是一般Pop up窗口在Show出来时会显示在最上面,而我们是要让它显示在最下面, 所以要设置下Z-Order:
这样上面的代码就实现了的窗口永远在桌面上,即使你点“显示桌面”或是WIN+D,也不受影响。
另外,如果你要让你的窗口在激活时也不会跑到其他窗口上面,只要创建时设置WS_EX_NOACTIVATE属性就可以了。
还有个问题是桌面Shell有可能重启,比如我们Kill掉Explorer.exe进程,所以我们最好一开始就启一个定时器,然后不停调用CheckParent(HWND hWnd)。
今天在QQ群里有人问怎样实现将自己的窗口嵌入桌面,让它和桌面融为一体,就像很多桌面日历软件那样。
我当时想到的就是建立一个Child Window,将他的父窗口设置成桌面Shell窗口就可以了。但是后来想想觉得不对,因为很多桌面日历窗口都有半透明和阴影效果,明显是用Layered Window实现的,而大家知道Layered Window一定要用Pop Up Window才能实现的。
那么如何用Pop up Window实现这种效果呢? 这里关键的一点就是要将该窗口的Owner设置成桌面的Shell 窗口。
很多以为Pop Up Window的Owner窗口只能在Create时关联, 建立后没法动态修改,实际上微软是有接口让我们改的,只是他们不建议我们动态改,因为这样会影响窗口的层次关系,尤其是对于Modal Dialog。
我们将窗口Owner改成桌面Shell窗口的代码如下:
BOOL CheckParent(HWND hWnd) { static HWND s_hWndOldParent = NULL; HWND hWndProgram = NULL; HWND hWndShellDLL = NULL; hWndProgram = FindWindow(_T("Progman"), _T("Program Manager")); if(hWndProgram != NULL) { hWndShellDLL = FindWindowEx(hWndProgram, NULL, _T("SHELLDLL_DefView"), NULL); } if(hWndShellDLL != NULL && hWndShellDLL != s_hWndOldParent) { SetWindowLong(hWnd, GWL_HWNDPARENT, (LONG)hWndShellDLL); s_hWndOldParent = hWndShellDLL; return TRUE; } return FALSE; }
另外还有一个问题是一般Pop up窗口在Show出来时会显示在最上面,而我们是要让它显示在最下面, 所以要设置下Z-Order:
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); CheckParent(hWnd); SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW);
这样上面的代码就实现了的窗口永远在桌面上,即使你点“显示桌面”或是WIN+D,也不受影响。
另外,如果你要让你的窗口在激活时也不会跑到其他窗口上面,只要创建时设置WS_EX_NOACTIVATE属性就可以了。
还有个问题是桌面Shell有可能重启,比如我们Kill掉Explorer.exe进程,所以我们最好一开始就启一个定时器,然后不停调用CheckParent(HWND hWnd)。
相关文章推荐
- 桌面上嵌入窗口(桌面日历)原理探索
- 桌面上嵌入窗口(桌面日历)原理探索# 欢迎使用Markdown编辑器写博客
- 桌面上嵌入窗口(桌面日历)原理探索(将该窗口的Owner设置成桌面的Shell 窗口,可使用SetWindowLong更改窗口的GWL_HWNDPARENT,还要使用SetWindowPos设置Z-Order)
- 关于窗口嵌入桌面及透明的注意事项
- 如何让你的WinForm嵌入桌面窗口最底层
- 利用jquery写的无限弹出移动窗口,仿桌面窗口移动,原理很简单
- Qt实现嵌入桌面的半透明窗口
- Qt实现半透明窗口 嵌入桌面
- c# 获取鼠标处窗口句柄,程序嵌入桌面
- 在Ubuntu Linux桌面上嵌入终端窗口
- 【转】C#如何让WinForm嵌入桌面窗口最底层
- 关于窗口嵌入桌面及透明的注意事项
- 关于窗口嵌入桌面及透明的注意事项
- Qt实现嵌入桌面的半透明窗口 [此博文包含图片]
- 把Winform程序窗口嵌入到桌面
- 将窗口嵌入桌面
- 将窗口嵌入桌面
- Qt实现嵌入桌面的半透明窗口
- 将窗口嵌入桌面
- 关于窗口嵌入桌面显示(桌面提示)