TrayApp (Tray Application): Quick launch applications by tray icon or hotkey.

作者:马健
邮箱:stronghorse_mj@hotmail.com
主页:老马的原创空间

功能简介
使用说明
密技曝光
    一、将所有窗口最小化
    二、带图标的动态菜单及其响应
    三、快捷方式的创建与解析
    四、TrayApp 的数据存储
附录 版本更新记录

功能简介

初识 Microsoft Windows 98 时,我感到最方便的地方就是 IE 4 所带的 Quick Launch 功能:在屏幕左下角任务条(taskbar)上,在“开始”按钮右侧,有一个区域,用户可以从“资源探测器”或“桌面”上拖动(drag & drop)文件到它上面,以后只要点击拖过来的图标,就可以执行程序、打开文件。

但在用了一段时间之后,我也发现了 Quick Luanch 的缺点:
1. 我的 Quick Launch 条上的图标越来越多,任务条都快被挤得没地方了。尤其在上网看新闻的时候,我经常先用“在新窗口中打开”功能点开所有想看的题目,再下线慢慢看,当任务条需要翻页的次数一多,整个系统将变得不稳定。
2. Quick Luanch 条上一次只能执行一个程序,我上网时需要依次点 NJStar、Netscape Navigate、IE、NetAnts、拨号网络等,心烦透顶。

因此我决定开发新的 Quick Launch 程序:在屏幕右下角 tray 区域增加一个图标(这就是名字中 Tray 一词的由来),用鼠标右键单击该图标时弹出一个小方块,用户可以将文件或目录拖动到这个小方块上,就象拖动到 IE 的 Quick Launch 条上一样;下次用户用鼠标左键单击 tray 图标时,弹出一个带小图标的菜单,包含用户拖过来的所有文件和目录(目录用多级或单级菜单表示),用户选择菜单就可以打开或执行文件,就象在 IE 的 Quick launch 条上点击图标一样;按住 Ctrl 键点击菜单项则执行与该菜单项同组的所有菜单。

由于 TrayApp 用菜单对快捷方式进行管理,不仅节省任务条上的空间,而且便于对功能进行分组,及按组执行。

从2.00版开始,TrayApp加入热键(hotkey)功能,可以通过热键快速启动运用程序。Windows自身有一些预定义的热键:Win+E打开资源管理器,Win+R打开“运行”,Win+M显示桌面,Win+U打开“辅助工具管理器”,等等。现在TrayApp 的用户也可以自己定义热键了,但是不能与Windows预定义的热键冲突。

定义热键后,会生成TrayApp.key文件,记录用户定义的热键。

注意:

TrayApp是一个Freeware,因此您没有为它付费的义务,也没有使用它的义务,更没有更改它或它的附件的权利;我没有为TrayApp提供服务的义务,也没有为使用TrayApp的后果承担责任的义务。但如果您喜欢它,您可以在不更改任何信息,也不添加、删减任何附件的情况下,出于非商业目的对它进行分发、复制。如果要将它用于商业目的,请与我联系,否则保留追究一切责任的权利。我的联系地址:stronghorse_mj@hotmail.com


使用说明

启动 TrayApp 后,在屏幕右下角 tray 区域会增加一个图标,

右键单击这个图标:在屏幕右下角出现一个小窗口,用户可以从“资源探测器”、“桌面”、IE 的 Quick Launch 条中拖动文件、文件夹(“控制面板”中的程序可以先创建快捷方式到“桌面”上,再从“桌面”拖动)到该窗口,程序在自身目录下创建一个子目录,记录这些文件、文件夹的快捷方式。下次用户左键单击图标时,根据记录的快捷方式生成动态菜单。用户单击该窗口将关闭它。

左键单击这个图标:显示动态菜单,菜单最下面一行为Toolbar32自己的菜单,包括Desktop、Edit、Auto Start、Dir As Separator、Help、About、Exit;中间是代表各快捷方式的菜单,含图标,多层或多组(代表多级目录结构),快捷方式可能指向某个可执行文件,也可能指向某个文档,用户单击菜单项时启动快捷方式所指向的可执行文件,或打开文档,按住 Ctrl 键点击菜单项则执行与该菜单项同组的所有菜单;最顶上一个菜单项是“<<Add New Item>>”,其作用相当于右键单击 tray 图标。

各菜单项的含义:

1. Desktop
将当前屏幕上的所有窗口最小化。这是给坚持使用 Windows 95 的穷兄弟们准备的,速度比 Windows 98 自带的功能差多了,代码也比较简单。

2. Show All
Desktop功能的反功能:将所有最小化的窗口恢复原大小。

3. Edit
弹出“资源探测器”,定位到 TrayApp 记录快捷方式的目录,用户可以删除不需要的快捷方式,或通过创建子目录来对快捷方式进行分组管理。

4. Hotkeys
定义、管理热键,按下指定的热键,即可快速启动对应的应用程序。
注意热键也是一种系统资源,因此第一不可与Windows预定义的热键或其他热键定义的热键冲突(如果有冲突,系统会提示修正);第二不易定义太多,最好只定义几个最常用的。
最简单的方法是只为TrayApp自身的快捷菜单定义热键,按下后立刻在鼠标当前位置处弹出TrayApp自身的快捷菜单,不必用鼠标到屏幕右下角点击。

5. Auto Start
是否在启动 Windows 时自动启动 TrayApp。

6. Dir As Separator
如果该项被选中,所有子目录下的快捷方式均在同一个菜单中显示,中间用分隔横线隔开;否则每个子目录创建一个子菜单,用多级菜单表示整个目录结构

7. Help
弹出缺省网络浏览器,显示本文件。

8. About
显示版本信息

9. Exit
退出程序

密技曝光

一、将所有窗口最小化

在 TrayApp 中通过一个循环实现该功能:

    HWND hwndParent = ::GetDesktopWindow();
   
    for (HWND hWnd = ::GetWindow(hwndParent, GW_CHILD);
        hWnd != NULL;
        hWnd = ::GetWindow(hWnd, GW_HWNDNEXT))
    {
        if (!::IsWindowVisible(hWnd)) continue;
        if (::IsIconic(hWnd)) continue;
        ::PostMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
    }

二、带图标的动态菜单及其响应

理论上讲,用 Windows API 提供的 CreatePopupMenu、AppendMenu 两个函数,就可以不依赖于资源文件中的菜单模板,用代码创建出所需的多级动态菜单。菜单项的 ID 需要自己定义(一般是顺序增长)。多级菜单一般按递归方式创建,以简化代码。

用 TrackPopupMenu 函数可以显示菜单并获得输入。但是 TrackPopupMenu 函数的参数不同,对用户输入的响应方式也不同。如果 TrackPopupMenu 函数的 uFlags 参数包含 TPM_RETURNCMD,则 TrackPopupMenu 函数的返回值就是用户所选菜单项的 ID;否则用户所选菜单项的 ID 通过 WM_COMMAND 消息的 wParam 参数的低字传入,程序员需要重载 CWnd::OnCmdMsg 函数对菜单项进行响应。

让菜单项带图标是通过创建 owner draw 菜单实现,在 MSDN 和其它网站中有不少这方面的例子。但是目前还没有谁公布的免费源代码能达到 Windows 98 “开始”菜单的水平:能够通过 drag & drop 动态调整菜单项的顺序。Netscape Navigator ver 4.5 的源代码支持 drop target,但不能是 source,即可以从网页上拖动网址到 Bookmarks 菜单,但是在 Bookmarks 菜单中不能直接通过拖动调整顺序,还必须到 Bookmark Editor 中才能编辑。在 Netscape Navigator 的最新版本(mozila)中,由于 UI 的变化,干脆放弃了对这个菜单的进一步研发,连文件都找不到了。说起来在现有基础上进一步改进并不是太难,因为目前 Windows 对 drag & drop 的支持已经提供了标准接口,不过实在是提不起劲头来。

三、快捷方式的创建与解析

Windows Shell 提供的 IShellLink、IPersistFile 接口提供了对快捷方式的所有管理功能,在 MSDN 中不仅有详细说明,还有快捷方式的创建、解析(Link Resolution)的完整示例代码,即使看不懂也没有关系,知道怎么 Copy & Paste 就行了。

四、TrayApp 的数据存储

和 IE 的 Quick Launch 一样,TrayApp 也是在自己创建的子目录中存储快捷方式,只不过 Quick Launch 存放的目录是 C:\WINDOWS\Application Data\Microsoft\Internet Explorer\Quick Launch,TrayApp 则是在自身 EXE 文件所在目录下的与 EXE 文件同名的子目录。在版本 1.3 以前则是在 EXE 文件所在目录下的名为 ShortCuts 的子目录。进行这样的改动,主要是因为我后来在我的计算机上同时装了 WinMe 和 WinNT 两个操作系统,我又不想为两个系统创建两个 Tools 目录,这样只需要有两个 EXE 就行了。

附录 版本更新记录

Version 2.08
错误修正:在热键定义里,如果Command有中文等特殊字符,会被截断。

Version 2.07
错误修正:在Win 10下以管理员权限运行后,从资源管理器不能拖拽打开文件。

Version 2.06
功能修正:动态生成菜单时,自动跳过隐藏文件。

Version 2.05
错误修正:某些情况下会出现资源漏洞。

Version 2.04
兼容32位色图标。

Version 2.03
新增功能:在热键定义界面中,允许为TrayApp自身的快捷菜单定义热键,按下后在鼠标当前位置处弹出TrayApp自身的快捷菜单,不必用鼠标到屏幕右下角点击。

Version 2.02
错误修正:按住Ctrl点击分组菜单项,会把其它菜单组中的程序也启动。

Version 2.01
错误修正:About对话框中部分信息显示不全。

Version 2.00
取消ANSI版,改为发行Unicode版。
新增功能:定义系统热键(hotkey),通过热键快速启动选定的软件。

Version 1.48
功能增强:启动时加入右下角图标如果一次不成功,会多次重试。

Version 1.47
错误修正:在VISTA下,点击“Edit”菜单没有反应。

Version 1.46
错误修正:某些时候右键点击右下角图标,不能正确显示带图标的小窗口。

Version 1.45
错误修正:在某些系统下,点击右下角图标会出错退出。

Version 1.44
功能增强:在选择“自动启动”菜单后,如果在注册表中创建启动项失败,则自动在启动组中创建,以防止因为在Windows域的组策略,或防病毒软件中禁止修改注册表而造成不能自动启动。
错误修正:在“待机”后再恢复,屏幕右下角图标消失。

Version 1.43
功能增强:在生成快捷方式时,快捷方式的名称中不再包含原文件的扩展名,以兼容瑞星2006。