WEB开发网
开发学院软件开发VC 系统托盘编程完全指南 阅读

系统托盘编程完全指南

 2010-07-25 20:46:55 来源:WEB开发网   
核心提示:CTrayIcon将此代码解释成NIM_DELETE,你已经看到,系统托盘编程完全指南(4),所有这些表示行为的编码,标志都被一个使用方便的函数所替代:这都归功于C++!现在,TrayTest1要做的事情不外乎调用CTrayIcon::OnTrayNotification实现一个通知消息处理器,提供一个与图标ID相同的

CTrayIcon将此代码解释成NIM_DELETE。你已经看到,所有这些表示行为的编码,标志都被一个使用方便的函数所替代:这都归功于C++!现在,我们来看看如何处理通知消息以及前面提到的所有UI特性。通知消息的处理必须要设置图标之前,但是要在创建窗口之后调用CTrayIcon::SetNotificationWnd,做这件事情的最佳场所是在OnCreate处理例程中,TrayTest就是在这里处理的:

// 注册用于托盘的自定义消息
#define WM_MY_TRAY_NOTIFICATION WM_USER+0
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
……
 // 请通知我
 m_trayIcon.SetNotificationWnd(this,
            WM_MY_TRAY_NOTIFICATION);
              m_trayIcon.SetIcon(IDI_MYICON);
 return 0;
}

消息一旦注册,接下来你便可以用通常的消息映射方式处理托盘通知消息。

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
 ON_MESSAGE(WM_MY_TRAY_NOTIFICATION,
       OnTrayNotification)
       // (or ON_REGISTERED_MESSAGE)
END_MESSAGE_MAP()
LRESULT
CMainFrame::OnTrayNotification(WPARAM wp, LPARAM lp)
{          
……
    // 显示消息
……
return m_trayIcon.OnTrayNotification(wp, lp);
}

当消息处理器得到控制,WPARAM的值是在构造CTrayIcon时指定的ID;LPARAM为鼠标事件(如WM_LBUTTONDOWN)。当你得到通知消息后,可以做任何想做的的事情;例子程序TrayTest此时是显示通知信息,细节请参考源代码。完成消息的处理之后,调用CTrayIcon::OnTrayNotification进行缺省处理。此虚拟函数(所以你可以改写)实现我前面提到过的缺省的UI行为。尤其是处理WM_LBUTTONDBLCLK和WM_RBUTTONUP。CTrayIcon寻找与图标ID相同的某个菜单(如IDR_TRAYICON),如果找到,则当用户右键单击图标时CTrayIcon显示这个菜单;当用户数双击图标时,CTrayIcon执行第一个菜单命令。只有两件事情需要进一步交待:

第一件事情是:在显示菜单之前,CTrayIcon让第一个菜单项为默认,所以它以黑体显示。但如何用黑体来显示某个菜单项呢?我在\MSDEV\INCLUDE\*.H搜索了一番,发现了Get/SetMenuDefaultItem。这个函数没有相关的CMenu打包类,所以我必须直接调用它们。

// 让第一个菜单项为默认(黑体):
::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);

这里0表示第一个菜单项,TRUE说明用位置表示菜单项的ID。为什么MFC没有打包Get/SetMenuDefaultItem函数呢?微软的家伙们解释那是因为这些函数(其它的还有::Get/SetMenuItemInfo, ::LoadImage等)还没有在最新的Windows版本中实现。一旦在最新的Windows版本中实现了,便会马上添加到MFC中。

第二件事情是上下文菜单的显示:

::SetForegroundWindow(m_nid.hWnd); ::TrackPopupMenu(pSubMenu->m_hMenu, ...);

为了让TrackPopupMenu在托盘的上下文中正确运行,你必须首先调用SetForegroundWindow,否则,当用户按下ESCAPE键或者在菜单之外单击鼠标时,菜单不会消失。为解决这个问题,我花费了数个小时,最后还是在MSDN上找到了解决方法。为了解详情,请参考MSDN的Q135788。最让我哭笑不得的是我花了那么多时间来关注这个问题,最后微软的这帮家伙在MSDN上给你来了一个问题的结论是:“This behavior is by design.....”真是气刹人也。

正如你所看到的,CTrayIcon使得托盘应用的编程变得易如反掌。TrayTest1要做的事情不外乎调用CTrayIcon::OnTrayNotification实现一个通知消息处理器,提供一个与图标ID相同的菜单。就这么简单。

// (TRAYTEST.RC文件)
IDR_TRAYICON MENU DISCARDABLE
BEGIN
  POPUP "托盘(&T)"
  BEGIN
    MENUITEM "打开(&O)",          ID_APP_OPEN
    MENUITEM "关于 TrayTest(&A)...",    ID_APP_ABOUT
    MENUITEM SEPARATOR
    MENUITEM "退出TrayTest 程序(&S)",    ID_APP_SUSPEND
  END
END

上一页  1 2 3 4 5  下一页

Tags:系统 托盘 编程

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接