飘遥的Blog

C/C++/.NET
posts - 126, comments - 199, trackbacks - 9, articles - 0
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

仿Win7显示桌面的工具

Posted on 2010-01-30 04:42  Zzx飘遥  阅读(...)  评论(... 编辑 收藏

 Win7改进了许多用户体验,其中右下角显示桌面的按钮是最舒心的功能之一。为了在没装Win7的开发机上体验这个功能,写了下面的小工具。
Win7中,鼠标拖到最右下角,点击左键,便可以显示桌面。

在用户体验上,右下角是一个无限大的区域(黄色边框范围),因为鼠标被限制在屏幕范围内;与屏幕中某块孤立范围相比,操作的命中率大大提高。
要实现这样的工具,思路非常简单:取得屏幕分辨率;在最右下角放置按钮或类似控件;点击时触发显示桌面;OK。当然还有一些细节如任务栏并不一定是在屏幕下方;最好不要影响到用户的正常操作,在用户不想看的时候甚至不要让用户看到;设置开机自动启动等。

按照这样的思路一点点实现即可。
取得任务栏,在上面添加子窗口:
hWndTray = FindWindow(TEXT("Shell_TrayWnd"), NULL);

CreateWindow(szWindowClass, szTitle, WS_CHILD,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWndTray, NULL, hInstance, NULL);

根据任务栏的位置不同,设置子窗口的位置及大小:
RECT rectTray, rectWnd;
const int CTL_LENGTH = 10;

if(!GetWindowRect(hWndTray, &rectTray))
{
    MessageBox(hWnd, TEXT(
"Get task bar size failed!"), szTitle, MB_OK);
    
return FALSE;
}

if(rectTray.bottom - rectTray.top < rectTray.right - rectTray.left)
{
    
//horizon
    rectWnd.left = rectTray.right - rectTray.left - CTL_LENGTH;
    rectWnd.right
= rectWnd.left + CTL_LENGTH;
    rectWnd.top
= 0;
    rectWnd.bottom
= rectTray.bottom - rectTray.top;
}
else
{
    
//vertical
    rectWnd.left = 0;
    rectWnd.right
= rectTray.right - rectTray.left;
    rectWnd.top
= rectTray.bottom - rectTray.top - CTL_LENGTH;
    rectWnd.bottom
= rectWnd.top + CTL_LENGTH;
}

SetWindowPos(hWnd, NULL, rectWnd.left, rectWnd.top, rectWnd.right
- rectWnd.left, rectWnd.bottom - rectWnd.top, 0); 

显示桌面调用SHELL的COM对象。
IShellDispatch4 * pshDsp4;
CoCreateInstance(CLSID_Shell, NULL, CLSCTX_SERVER, IID_IDispatch, (VOID
**)&pshDsp4);
pshDsp4
->ToggleDesktop();

如果设置为自动运行,在注册表HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run下添加键值。
在程序运行中,如果主题修改或任务栏位置修改,需要更新窗口的位置,处理WM_SETTINGCHANGE消息即可。

要使子窗口透明,程序实现上比较麻烦,可以阻止系统对WM_ERASEBKGND消息的默认处理,以达到窗口“透明”的目的(不处理背景重绘,当然某些情况下会显示不正常)。

最终运行截图:(点右键显示的菜单)


在WinXP,Win7简单测试通过。

源码及可执行程序下载:点击下载