公告:     清河论坛已经开通,开始测试了!!!!!!  [王嵩峰  2006年9月15日]        
您现在的位置: 清河在线 >> 设计教程 >> 程序开发 >> 教程正文
最新热门教程
最新推荐教程
广告载入中...
Visual C++窗体设计灵活技术集2     ★★★
Visual C++窗体设计灵活技术集2
副标题:Visual C++窗体设计灵活技术集2
作者:佚名    教程来源:本站原创    点击数:    更新时间:2007-3-11

ELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage,PNOTIFYICONDATA pnid);

   DwMessage为所发送消息的标志:

    NIM_ADD 添加图标到任务栏通知区;

    NIM_DELETE 删除任务栏通知区的图标;

    NIM_MODIFY 更改任务栏通知区的图标、回调消息标志、回调窗口句柄或提示字串;

    pnid为NOTIFYICONDATA结构的指针。

   回调信息的获得及处理

   如果一个任务栏图标有应用程序定义的回调消息,那么当这个图标有鼠标操作时,系统将给hWnd所标志的窗口发送下列的消息:


messageID = uCallbackMessage
wParam = uID
lParam = mouse event(例如WM_LBUTTONDOWN)

   通过这种方式,系统通知应用程序用户对图标的操作。如果一个应用程序生成了两个以上的图标,那么你可以根据wParam来判断是哪个图标返回的鼠标操作。通常,标准的Win95任务栏图标有以下鼠标操作响应:

   当鼠标停留在图标上时,系统应显示提示信息tooltip;

   当使用鼠标右键单击图标时,应用程序应显示快捷菜单;

   当使用鼠标左键双击图标时,应用程序应执行快捷菜单的缺省菜单项。

   在Microsoft Windows环境中,0x8000到0xBFFF的消息是保留的,应用程序可以定义自定义消息。

   关于消息处理的详细内容,请参考下一部分。

   源码及实现

   在本文中关于任务栏图标的类叫做CTrayIcon,这个类由CCmdTarget(或CObject)类派生,它有如下的成员变量和成员函数:

// TrayIcon.h
// CTrayIcon command target
class CTrayIcon : public CCmdTarget
{
public:
NOTIFYICONDATA m_nid;//NOTIFYICONDATA结构,你的图标要用的啊
BOOL m_IconExist;//标志,看看图标是不是已经存在了
CWnd* m_NotificationWnd;//接受回调消息的窗口,有它就不必经常AfxGetMainWnd了
public:
CWnd* GetNotificationWnd() const;//得到m_NotificationWnd
BOOL SetNotificationWnd(CWnd* pNotifyWnd);//设置(更改)m_NotificationWnd
CTrayIcon();//构造函数
virtual ~CTrayIcon();//析构函数
BOOL CreateIcon(CWnd* pNotifyWnd, UINT uID, HICON hIcon,
LPSTR lpszTip, UINT CallBackMessage);//在任务栏上生成图标
BOOL DeleteIcon();//删除任务栏上的图标
virtual LRESULT OnNotify(WPARAM WParam, LPARAM LParam);//消息响应函数
BOOL SetTipText(UINT nID);//设置(更改)提示字串
BOOL SetTipText(LPCTSTR lpszTip);//设置(更改)提示字串
BOOL ChangeIcon(HICON hIcon);//更改图标
BOOL ChangeIcon(UINT nID);//更改图标
BOOL ChangeIcon(LPCTSTR lpszIconName);//更改图标
BOOL ChangeStandardIcon(LPCTSTR lpszIconName);//更改为标准图标
......
};


   下面是成员函数的定义:

// TrayIcon.cpp
// CTrayIcon
CTrayIcon::CTrayIcon()
{//初始化参数
m_IconExist = FALSE;
m_NotificationWnd = NULL;
memset(&m_nid, 0, sizeof(m_nid));
m_nid.cbSize = sizeof(m_nid);//这个参数不会改变
}

CTrayIcon::~CTrayIcon()
{
if (m_IconExist)
DeleteIcon();//删除图标
}

BOOL CTrayIcon::CreateIcon(CWnd* pNotifyWnd, UINT uID, HICON hIcon,
LPSTR lpszTip, UINT CallBackMessage)
{
//确定接受回调消息的窗口是有效的
ASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->GetSafeHwnd()));

ASSERT(CallBackMessage >= WM_USER);//确定回调消息不发生冲突

ASSERT(_tcslen(lpszTip) <= 64);//提示字串不能超过64个字符

m_NotificationWnd = pNotifyWnd;//获得m_NotificationWnd

//设置NOTIFYICONDATA结构
m_nid.hWnd = pNotifyWnd->GetSafeHwnd();
m_nid.uID = uID;
m_nid.hIcon = hIcon;
m_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
m_nid.uCallbackMessage = CallBackMessage;

//设置NOTIFYICONDATA结构的提示字串
if (lpszTip)
lstrcpyn(m_nid.szTip, lpszTip, sizeof(m_nid.szTip));
else
m_nid.szTip[0] = '';

//显示图标
m_IconExist = Shell_NotifyIcon(NIM_ADD, &m_nid);
return m_IconExist;
}

BOOL CTrayIcon::DeleteIcon()
{//删除图标
if (!m_IconExist)
return FALSE;
m_IconExist = FALSE;
return Shell_NotifyIcon(NIM_DELETE, &m_nid);
}

LRESULT CTrayIcon::OnNotify(WPARAM WParam, LPARAM LParam)
{//处理图标返回的消息
if (WParam != m_nid.uID)//如果不是该图标的消息则迅速返回
return 0L;

//准备快捷菜单
CMenu menu;
if (!menu.LoadMenu(IDR_POPUP))//你必须确定资源中有ID为IDR_POPUP的菜单
return 0;
CMenu* pSubMenu = menu.GetSubMenu(0);//获得IDR_POPUP的子菜单
if (!pSubMenu)
return 0;

if (LParam == WM_RBUTTONUP)
{//右键单击弹出快捷菜单

//设置第一个菜单项为缺省
::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);
CPoint pos;
GetCursorPos(&pos);

//显示并跟踪菜单
m_NotificationWnd->SetForegroundWindow();
pSubMenu->TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON
|TPM_RIGHTBUTTON, pos.x, pos.y, m_NotificationWnd, NULL);
}
else if (LParam == WM_LBUTTONDOWN)
{//左键单击恢复窗口
m_NotificationWnd->ShowWindow(SW_SHOW);//恢复窗口
m_NotificationWnd->SetForegroundWindow();//放置在前面
}
else if (LParam == WM_LBUTTONDBLCLK)
{//左键双击执行缺省菜单项
m_NotificationWnd->SendMessage(WM_COMMAND,
pSubMenu->GetMenuItemID(0), 0);
}
return 1L;
}

BOOL CTrayIcon::SetTipText(LPCTSTR lpszTip)
{//设置提示文字
if (!m_IconExist)
return FALSE;

_tcscpy(m_nid.szTip, lpszTip);
m_nid.uFlags |= NIF_TIP;

return Shell_NotifyIcon(NIM_MODIFY, &m_nid);
}

BOOL CTrayIcon::SetTipText(UINT nID)
{//设置提示文字
  CString szTip;
  VERIFY(szTip.LoadString(nID));

  return SetTipText(szTip);
}
BOOL CTrayIcon::ChangeIcon(HICON hIcon)
{//更改图标
if (!m_IconExist)
return FALSE;

m_nid.hIcon = hIcon;
m_nid.uFlags |= NIF_ICON;

return Shell_NotifyIcon(NIM_MODIFY, &m_nid);
}

BOOL CTrayIcon::ChangeIcon(UINT nID)
{//更改图标
  HICON hIcon = AfxGetApp()->LoadIcon(nID);
  return ChangeIcon(hIcon);

}

BOOL CTrayIcon::ChangeIcon(LPCTSTR lpszIconName)
{//更改图标
  HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName);
  return ChangeIcon(hIcon);
}

BOOL CTrayIcon::ChangeStandardIcon(LPCTSTR lpszIconName)
{//更改为标准图标
  HICON hIcon = AfxGetApp()->LoadStandardIcon(lpszIconName);
  return ChangeIcon(hIcon);
}

BOOL CTrayIcon::SetNotificationWnd(CWnd * pNotifyWnd)
{//设置接受回调消息的窗口
  if (!m_IconExist)
   return FALSE;

  //确定窗口是有效的
  ASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->GetSafeHwnd()));

  m_NotificationWnd = pNotifyWnd;
  m_nid.hWnd = pNotifyWnd->GetSafeHwnd();
  m_nid.uFlags |= NIF_MESSAGE;

  return Shell_NotifyIcon(NIM_MODIFY, &m_nid);
}

CWnd* CTrayIcon::GetNotificationWnd() const
{//返回接受回调消息的窗口
  return m_NotificationWnd;
}


   三点补充:

   关于使用回调消息的补充说明:


   首先,在MainFrm.cpp中加入自己的消息代码;


// MainFrm.cpp : implementation of the CMainFrame class
//
#define MYWM_ICONNOTIFY WM_USER + 10//定义自己的消息代码

   第二步增加消息映射和函数声明,对于自定义消息不能由ClassWizard添加消息映射,只能手工添加。


// MainFrm.cpp : implementation of the CMainFrame class
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
//其他的消息映射
......
//}}AFX_MSG_MAP
ON_MESSAGE(WM_ICONNOTIFY,OnNotify)
END_MESSAGE_MAP()
并且在头文件中添加函数声明
// MainFrm.h
afx_msg LRESULT OnNotify(WPARAM WParam, LPARAM LParam);

   第三步增加消息处理函数定义


LRESULT CMainFrame::OnNotify(WPARAM WParam, LPARAM LParam)
{
return trayicon.OnNotify(WParam, LParam);//调用CTrayIcon

类的处理函数
}

   如何隐藏任务栏上的按钮

   可以使用下列两种方法:

   1.在CreateWindowEx函数中使用WS_EX_TOOLWINDOW窗口式样(相反的如果要确保应用程序在任务栏上生成按钮,可以使用WS_EX_APPWINDOW窗口式样)。 The problem with this is that the window decorations are as for a small floating toolbar, which isn't normally what's wanted.

   2.生成一个空的隐藏的top-level窗口,并使其作为可视窗口的父窗口。

   3.在应用程序的InitInstance()函数中使用SW_HIDE式样调用ShowWindow()函数。


//pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->ShowWindow(SW_HIDE);
pMainFrame->UpdateWindow();

   如何动画任务栏上的图标


   在TrayIcon类中加入下列两个函数:

BOOL CTrayIcon::SetAnimateIcons(HICON* hIcon, UINT Number)
{//设置动画图标
  ASSERT(Number >= 2);//图标必须为两个以上
  ASSERT(hIcon);//图标必须不为空
  m_AnimateIcons = new HICON[Number];
  CopyMemory(m_AnimateIcons, hIcon, Number * sizeof(HICON));
  m_AnimateIconsNumber = Number;
  return TRUE;
}

BOOL CTrayIcon::Animate(UINT Index)
{//动画TrayIcon
  UINT i = Index % m_AnimateIconsNumber;
  return ChangeIcon(m_AnimateIcons[i]);
}


   怎样在应用程序中添加相应的菜单和函数

void CMainFrame::OnMenuAnimate()
{//动画TrayIcon,设置图标及定时器
  SetTimer(1, 500, NULL);
  HICON hIcon[3];
  hIcon[0] = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  hIcon[1] = AfxGetApp()->LoadIcon(IDR_MYTURNTYPE);
  hIcon[2] = AfxGetApp()->LoadStandardIcon(IDI_HAND);
  trayicon.SetAnimateIcons(hIcon, 3);
}
void CMainFrame::OnTimer(UINT nIDEvent)
{//动画TrayIcon
  UINT static i;
  i += 1;
  trayicon.Animate(i);

  CMDIFrameWnd::OnTimer(nIDEvent);
}  

教程录入:HBctong    责任编辑:HBctong 
  • 上一篇教程:
  • 下一篇教程: 没有了
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    (只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    姓 名: * Oicq:
    性 别: Msn:
    E-mail: Icq:
    主 页:
    评 分: 1分 2分 3分 4分 5分
    评论内容:
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  • 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 |   

    感谢邢台创通公司 提供空间 | 冀ICP备05018085号

    清河在线 All Rights Reserved (C) Copyright 2006 TEL:0319-7502356     创通网站工作室
    清河在线 *卡通版*