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);
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);
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();
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简单测试通过。
源码及可执行程序下载:点击下载