📄 windows系统控制.htm
字号:
<html><style type="text/css"><!--.p9 { font-family: "宋体"; font-size: 9pt}a {text-transform: none; text-decoration: none;}a:hover {text-decoration: underline; color: #FF0000;}--></style><body background="di2001.jpg"><h3 align="center"><font COLOR="#AOAO99">WINDOWS系统控制</font></h3><table width="100%"><tr><td><font color="0000FF"><a name="1">在任务栏状态区显示应用程序图标</a></font></td></tr><tr><td><p></Br>数据结构:<Br></Br>有关的数据由NOTIFYICONDATA结构描述:<Br></Br>typedef struct _NOTIFYICONDATA<Br>{<Br> DWORD cbSize; //结构的大小,必须设置<Br> HWND hWnd; //接受回调消息的窗口的句柄<Br> UINT uID; //应用程序定义的图标标志<Br> UINT uFlags; //标志,可以是NIF_ICON、NIF_MESSAGE、NIF_TIP或其组合<Br> UINT uCallbackMessage;//应用程序定义的回调消息标志<Br> HICON hIcon; //图标句柄<Br> char szTip[64]; //提示字串<Br>} NOTIFYICONDATA, *PNOTIFYICONDATA;<Br></Br>函数说明<Br></Br>由Shell_NotifyIcon()函数向系统发送添加、删除、更改图标的消息。<Br></Br>WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage,PNOTIFYICONDATA pnid);<Br></Br>DwMessage为所发送消息的标志:<Br> NIM_ADD 添加图标到任务栏通知区;<Br> NIM_DELETE 删除任务栏通知区的图标;<Br> NIM_MODIFY 更改任务栏通知区的图标、回调消息标志、回调窗口句柄或提示字串;<Br>pnid为NOTIFYICONDATA结构的指针。<Br></Br>回调信息的获得及处理<Br></Br>如果一个任务栏图标有应用程序定义的回调消息,那么当这个图标有鼠标操作时,系统将给hWnd所标志的窗口发送下列的消息:<Br>messageID = uCallbackMessage<Br>wParam = uID<Br>lParam = mouse event(例如WM_LBUTTONDOWN)<Br></Br>通过这种方式,系统通知应用程序用户对图标的操作。如果一个应用程序生成了两个以上的图标,那么你可以根据wParam来判断是哪个图标返回的鼠标操作。通常,标准的Win95任务栏图标有以下鼠标操作响应:<Br></Br>当鼠标停留在图标上时,系统应显示提示信息tooltip;<Br>当使用鼠标右键单击图标时,应用程序应显示快捷菜单;<Br>当使用鼠标左键双击图标时,应用程序应执行快捷菜单的缺省菜单项。<Br></Br>在Microsoft Windows环境中,0x8000到0xBFFF的消息是保留的,应用程序可以定义自定义消息。<Br></Br>关于消息处理的详细内容,请参考下一部分。<Br></Br>源码及实现<Br></Br>在本文中关于任务栏图标的类叫做CTrayIcon,这个类由CCmdTarget(或CObject)类派生,它有如下的成员变量和成员函数:<Br></Br>// TrayIcon.h<Br>// CTrayIcon command target<Br></Br>class CTrayIcon : public CCmdTarget<Br>{<Br>public:<Br> NOTIFYICONDATA m_nid;//NOTIFYICONDATA结构,你的图标要用的啊<Br> BOOL m_IconExist;//标志,看看图标是不是已经存在了<Br> CWnd* m_NotificationWnd;//接受回调消息的窗口,有它就不必经常AfxGetMainWnd了<Br>public:<Br> CWnd* GetNotificationWnd() const;//得到m_NotificationWnd<Br> BOOL SetNotificationWnd(CWnd* pNotifyWnd);//设置(更改)m_NotificationWnd<Br> CTrayIcon();//构造函数<Br> virtual ~CTrayIcon();//析构函数<Br> BOOL CreateIcon(CWnd* pNotifyWnd, UINT uID, HICON hIcon,<Br> LPSTR lpszTip, UINT CallBackMessage);//在任务栏上生成图标<Br> BOOL DeleteIcon();//删除任务栏上的图标<Br> virtual LRESULT OnNotify(WPARAM WParam, LPARAM LParam);//消息响应函数<Br> BOOL SetTipText(UINT nID);//设置(更改)提示字串<Br> BOOL SetTipText(LPCTSTR lpszTip);//设置(更改)提示字串<Br> BOOL ChangeIcon(HICON hIcon);//更改图标<Br> BOOL ChangeIcon(UINT nID);//更改图标<Br> BOOL ChangeIcon(LPCTSTR lpszIconName);//更改图标<Br> BOOL ChangeStandardIcon(LPCTSTR lpszIconName);//更改为标准图标<Br> ......<Br>};<Br></Br>下面是成员函数的定义:<Br></Br>// TrayIcon.cpp<Br>// CTrayIcon<Br></Br>CTrayIcon::CTrayIcon()<Br>{//初始化参数<Br> m_IconExist = FALSE;<Br> m_NotificationWnd = NULL;<Br> memset(&m_nid, 0, sizeof(m_nid));<Br> m_nid.cbSize = sizeof(m_nid);//这个参数不会改变<Br>}<Br></Br>CTrayIcon::~CTrayIcon()<Br>{<Br> if (m_IconExist)<Br> DeleteIcon();//删除图标<Br>}<Br></Br>BOOL CTrayIcon::CreateIcon(CWnd* pNotifyWnd, UINT uID, HICON hIcon,<Br> LPSTR lpszTip, UINT CallBackMessage)<Br>{<Br> //确定接受回调消息的窗口是有效的<Br> ASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->GetSafeHwnd()));<Br></Br> ASSERT(CallBackMessage >= WM_USER);//确定回调消息不发生冲突<Br></Br> ASSERT(_tcslen(lpszTip) <= 64);//提示字串不能超过64个字符<Br></Br> m_NotificationWnd = pNotifyWnd;//获得m_NotificationWnd<Br></Br> //设置NOTIFYICONDATA结构<Br> m_nid.hWnd = pNotifyWnd->GetSafeHwnd();<Br> m_nid.uID = uID;<Br> m_nid.hIcon = hIcon;<Br> m_nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;<Br> m_nid.uCallbackMessage = CallBackMessage;<Br></Br> //设置NOTIFYICONDATA结构的提示字串<Br> if (lpszTip)<Br> lstrcpyn(m_nid.szTip, lpszTip, sizeof(m_nid.szTip));<Br> else<Br> m_nid.szTip[0] = '\0';<Br></Br> //显示图标<Br> m_IconExist = Shell_NotifyIcon(NIM_ADD, &m_nid);<Br> return m_IconExist;<Br>}<Br></Br>BOOL CTrayIcon::DeleteIcon()<Br>{//删除图标<Br> if (!m_IconExist)<Br> return FALSE;<Br> m_IconExist = FALSE;<Br> return Shell_NotifyIcon(NIM_DELETE, &m_nid);<Br>}<Br></Br>LRESULT CTrayIcon::OnNotify(WPARAM WParam, LPARAM LParam)<Br>{//处理图标返回的消息<Br> if (WParam != m_nid.uID)//如果不是该图标的消息则迅速返回<Br> return 0L;<Br></Br> //准备快捷菜单<Br> CMenu menu;<Br> if (!menu.LoadMenu(IDR_POPUP))//你必须确定资源中有ID为IDR_POPUP的菜单<Br> return 0;<Br> CMenu* pSubMenu = menu.GetSubMenu(0);//获得IDR_POPUP的子菜单<Br> if (!pSubMenu)<Br> return 0;<Br></Br> if (LParam == WM_RBUTTONUP)<Br> {//右键单击弹出快捷菜单<Br></Br> //设置第一个菜单项为缺省<Br> ::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);<Br> CPoint pos;<Br> GetCursorPos(&pos);<Br></Br> //显示并跟踪菜单<Br> m_NotificationWnd->SetForegroundWindow();<Br> pSubMenu->TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON<Br> |TPM_RIGHTBUTTON, pos.x, pos.y, m_NotificationWnd, NULL);<Br> }<Br> else if (LParam == WM_LBUTTONDOWN)<Br> {//左键单击恢复窗口<Br> m_NotificationWnd->ShowWindow(SW_SHOW);//恢复窗口<Br> m_NotificationWnd->SetForegroundWindow();//放置在前面<Br> }<Br> else if (LParam == WM_LBUTTONDBLCLK)<Br> {//左键双击执行缺省菜单项<Br> m_NotificationWnd->SendMessage(WM_COMMAND,<Br> pSubMenu->GetMenuItemID(0), 0);<Br> }<Br> return 1L;<Br>}<Br></Br>BOOL CTrayIcon::SetTipText(LPCTSTR lpszTip)<Br>{//设置提示文字<Br> if (!m_IconExist)<Br> return FALSE;<Br></Br> _tcscpy(m_nid.szTip, lpszTip);<Br> m_nid.uFlags |= NIF_TIP;<Br></Br> return Shell_NotifyIcon(NIM_MODIFY, &m_nid);<Br>}<Br></Br>BOOL CTrayIcon::SetTipText(UINT nID)<Br>{//设置提示文字<Br> CString szTip;<Br> VERIFY(szTip.LoadString(nID));<Br></Br> return SetTipText(szTip);<Br>}<Br>BOOL CTrayIcon::ChangeIcon(HICON hIcon)<Br>{//更改图标<Br> if (!m_IconExist)<Br> return FALSE;<Br></Br> m_nid.hIcon = hIcon;<Br> m_nid.uFlags |= NIF_ICON;<Br></Br> return Shell_NotifyIcon(NIM_MODIFY, &m_nid);<Br>}<Br></Br>BOOL CTrayIcon::ChangeIcon(UINT nID)<Br>{//更改图标<Br> HICON hIcon = AfxGetApp()->LoadIcon(nID);<Br> return ChangeIcon(hIcon);<Br>}<Br></Br>BOOL CTrayIcon::ChangeIcon(LPCTSTR lpszIconName)<Br>{//更改图标<Br> HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName);<Br> return ChangeIcon(hIcon);<Br>}<Br></Br>BOOL CTrayIcon::ChangeStandardIcon(LPCTSTR lpszIconName)<Br>{//更改为标准图标<Br> HICON hIcon = AfxGetApp()->LoadStandardIcon(lpszIconName);<Br> return ChangeIcon(hIcon);<Br>}<Br></Br>BOOL CTrayIcon::SetNotificationWnd(CWnd * pNotifyWnd)<Br>{//设置接受回调消息的窗口<Br> if (!m_IconExist)<Br> return FALSE;<Br></Br> //确定窗口是有效的<Br> ASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->GetSafeHwnd()));<Br></Br> m_NotificationWnd = pNotifyWnd;<Br> m_nid.hWnd = pNotifyWnd->GetSafeHwnd();<Br> m_nid.uFlags |= NIF_MESSAGE;<Br></Br> return Shell_NotifyIcon(NIM_MODIFY, &m_nid);<Br>}<Br></Br>CWnd* CTrayIcon::GetNotificationWnd() const<Br>{//返回接受回调消息的窗口<Br> return m_NotificationWnd;<Br>}<Br></Br></Br>三点补充:<Br>关于使用回调消息的补充说明:<Br></Br>首先,在MainFrm.cpp中加入自己的消息代码;<Br>// MainFrm.cpp : implementation of the CMainFrame class<Br>//<Br>#define MYWM_ICONNOTIFY WM_USER + 10//定义自己的消息代码<Br></Br>第二步增加消息映射和函数声明,对于自定义消息不能由ClassWizard添加消息映射,只能手工添加。<Br>// MainFrm.cpp : implementation of the CMainFrame class<Br>BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)<Br> //{{AFX_MSG_MAP(CMainFrame)<Br> //其他的消息映射<Br> ......<Br> //}}AFX_MSG_MAP<Br> ON_MESSAGE(WM_ICONNOTIFY,OnNotify)<Br>END_MESSAGE_MAP()<Br>并且在头文件中添加函数声明<Br>// MainFrm.h<Br>afx_msg LRESULT OnNotify(WPARAM WParam, LPARAM LParam);<Br></Br>第三步增加消息处理函数定义<Br>LRESULT CMainFrame::OnNotify(WPARAM WParam, LPARAM LParam)<Br>{<Br> return trayicon.OnNotify(WParam, LParam);//调用CTrayIcon类的处理函数<Br>}<Br></Br>如何隐藏任务栏上的按钮:<Br></Br>可以使用下列两种方法:<Br>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.<Br>2.生成一个空的隐藏的top-level窗口,并使其作为可视窗口的父窗口。<Br>3.在应用程序的InitInstance()函数中使用SW_HIDE式样调用ShowWindow()函数。<Br>//pMainFrame->ShowWindow(m_nCmdShow);<Br>pMainFrame->ShowWindow(SW_HIDE);<Br>pMainFrame->UpdateWindow();<Br></Br>如何动画任务栏上的图标:<Br></Br>在TrayIcon类中加入下列两个函数:<Br></Br>BOOL CTrayIcon::SetAnimateIcons(HICON* hIcon, UINT Number)<Br>{//设置动画图标<Br> ASSERT(Number >= 2);//图标必须为两个以上<Br> ASSERT(hIcon);//图标必须不为空<Br></Br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -