简单的动画托盘图标






4.64/5 (11投票s)
2002年2月5日
3分钟阅读

231347

5791
这是一个类 (SS_TrayIcon),它允许轻松地将托盘图标添加到任何项目中(无论您是否使用 MFC)。
引言
这是一个类 (SS_TrayIcon
),它在系统托盘中创建一个托盘图标,允许轻松地集成到任何项目中,无论您是否使用 MFC。 一些功能包括- 创建多个图标、动画图标、闪烁图标或静态图标
- 轻松定义一个消息映射,用于将托盘图标生成的 Windows 消息路由到用户定义的函数...
-或-
让 MFC 通过将所有消息发送到CWnd::WindowProc
函数来处理消息映射。 - 当用户单击图标时,轻松添加一个弹出窗口(上下文菜单)到该图标。
- 避免在用户双击之前处理
WM_LBUTTONDOWN
Windows 消息。 这是一个常见的问题...当用户双击时,程序通常在处理双击之前处理单次点击。 此类将等待发送单次点击消息,直到它确定用户不会双击。 (注意:如果您让 MFC 处理消息路由,则此功能不起作用。)
此类类似于 Chris Maunder 的类,位于 将图标添加到系统托盘 中,但它允许您指定模式 (SSTI_MODE_SHOWNORMAL
, SSTI_MODE_HIDE
, SSTI_MODE_BLINK
, SSTI_MODE_ANIMATE
)
包含一个简单的演示项目
集成到您的项目
您需要在您的项目中包含 2 个头文件(SS_TrayIcon.h 和 SS_Wnd.h),将 SS_TrayIconD.lib 文件添加到您的调试项目,并将 SS_TrayIcon.lib 文件添加到您的发布项目。 (或者您可以跳过 lib 文件并添加两个 *.cpp 文件。)要创建一个托盘图标,您只需要 3 行代码
SS_TrayIcon* m_pTrayIcon = new SS_TrayIcon( m_hInstance, 1, 1 ); // create the instance m_pTrayIcon->LoadIcon( 0, 0, IDI_SOME_ICON_RESOURCE ); // load an icon resource m_pTrayIcon->ShowIcon( 0 ); // show it!一些其他选项包括
m_pTrayIcon->Mode( 0, SSTI_MODE_BLINK ); // make it blink m_pTrayIcon->SetAnimateSpeed( 0, 400 ); // 400 is milliseconds m_pTrayIcon->ToolTip( 0, _T("This is a blinking icon...") ); // add a tool tip m_pTrayIcon->ShowMenuAtMouse( nMenuResourceID, hWnd ); // show a popup menu m_pTrayIcon->HideIcon(); // hide it!大多数修改图标的函数都需要一个整数作为第一个参数 (
nIconSet
)。 因为您可以有多个图标,所以此整数指定您要修改哪个图标。 然后,当您显示图标时,您指定要显示的图标。 从这里开始,我们将把这些图标中的每一个称为一个 IconSet
... 这就是原因:每个 IconSet
可以包含多个“子图标”,我们将其称为“帧”。 因此,每个 IconSet
构成一个动画,该动画由一定数量的帧组成。 您可以将图标资源加载到您的 IconSets
的帧中,如下面的代码所示,它创建了 3 个 IconSets
,一个有 8 帧,两个只有 1 帧// How many icons (IconSets)? // | How many icons per set (frames)? // | | m_pTrayIcon = new SS_TrayIcon( AfxGetInstanceHandle(), 3, 8 ); // prep IconSet 1 (animated with 8 frames) // // This is which IconSet to load into... // | This is the frame number... // | | m_pTrayIcon->LoadIcon( 0, 0, IDI_ICON1 ); m_pTrayIcon->LoadIcon( 0, 1, IDI_ICON2 ); m_pTrayIcon->LoadIcon( 0, 2, IDI_ICON3 ); m_pTrayIcon->LoadIcon( 0, 3, IDI_ICON4 ); m_pTrayIcon->LoadIcon( 0, 4, IDI_ICON5 ); m_pTrayIcon->LoadIcon( 0, 5, IDI_ICON4 ); m_pTrayIcon->LoadIcon( 0, 6, IDI_ICON3 ); m_pTrayIcon->LoadIcon( 0, 7, IDI_ICON2 ); m_pTrayIcon->Mode( 0, SSTI_MODE_ANIMATE ); m_pTrayIcon->SetAnimateSpeed( 0, 150 ); m_pTrayIcon->ToolTip( 0, _T("This is an animated icon...") ); // prep IconSet 2 (blinking) // m_pTrayIcon->LoadIcon( 1, 0, IDR_MAINFRAME ); m_pTrayIcon->Mode( 1, SSTI_MODE_BLINK ); m_pTrayIcon->SetAnimateSpeed( 0, 450 ); m_pTrayIcon->ToolTip( 1, _T("This is a blinking icon...") ); // prep IconSet 3 (standing still) // m_pTrayIcon->LoadIcon( 2, 0, IDI_ICON6 ); m_pTrayIcon->Mode( 2, SSTI_MODE_SHOWNORMAL ); m_pTrayIcon->ToolTip( 2, _T("This is a non-animated icon...") ); // Now show the first (animated) icon // m_pTrayIcon->ShowIcon( 0 ); // or '1' for the second, or '2' for the third您需要了解的最后一件事是消息映射。 对于您要响应的每条消息,您需要调用
m_pTrayIcon->MapMessageToFunction
函数。 您需要为该函数提供一个指向您的全局回调函数的指针,以便它可以在生成消息时调用该函数,如下所示// *global* callback function for the WM_LBUTTONDBLCLK message LRESULT CALLBACK OnMouseDblClickTI(WPARAM wParam, LPARAM lParam) { ::MessageBox(NULL, _T("Double-clicked!!"), _T("Test"), MB_OK|MB_ICONINFORMATION); return 0; } // in your initialization routine CYourClass::InitObject() { ... m_pTrayIcon = new SS_TrayIcon( AfxGetInstanceHandle(), 3, 8 ); m_pTrayIcon->MapMessageToFunction(WM_LBUTTONDBLCLK, ::OnMouseDblClickTI); ... }现在,无论用户双击托盘图标(无论您显示哪个图标),您的
OnMouseDblClickTI()
函数都将被调用。 您可以从那里做任何您想做的事情。 如果您想根据您显示的图标做出不同的响应,您将需要在回调函数中跟踪哪个图标正在显示,并使用一个 switch 语句来确定适当的操作。注释
演示代码中有很多注释解释了如何使用 SS_TrayIcon
类,并且 SS_TrayIcon
代码中也有很多注释解释了代码的工作原理,因此请通读这些注释以获得对该项目的内部工作原理的更详细解释。