在Win 95任务栏上放置图标
Windows 95(以下简称Win95)以其良好的用户界面深受广大用户喜爱。Win95启动后通过开始菜单或桌面上的快捷方式启动应用程序,一般情况下,当程序执行极小化操作后,程序将排列 到任务栏并以标题的形式显示,用户通过任务栏可以快速在各任务之间切换。但是对于那些针对系统时钟、设备状态或其它一些事件,如中文输入法等应用程序,其常见操作往往是说明当前时钟、设备或事件的状态以及在各状态之间的切换等。如果只是以标题的形式缩小到任务栏,用户需要查询和修改时需要重新激活应用程序窗口来操作,使用不方便。如果能像我们常见的Win95的音量控制和时钟一样把应用程序以图标的形式放入任务栏,那么不仅当前设备或事件的状态一目了然,而且可以通过鼠标和弹出菜单来改变,必要时还能重新激活应用程序主窗口来进行进一步操作。这无疑有助于提高程序的易用性,实现友好的用户界面。下面笔者结合一个在Borlard C++5.0下编制的实例程序来演示在Win95任务栏上放置图标的方法。
任务栏上的图标用结构NOTIFYICONDATA描述,结构NOTIFYICONDATA有两种形式NOTIFYIC ONDATAA和NOTIFYICONDATAW,两种结构的选择取决于使用的字符集,其定义在shellapi.h中。
struct NOTIFYICONDATAA {
DWORD cbSize; /*结构字节大小 */
HWND hWnd; /*窗口句柄*/
UINI u ID; /*图标标识*/
UINT uFlags;
/* 标志可以是NIF-MESSAGE(传递消息)、NIF-ICON(显示图标)、NIF-TIP(显示提示)的组合*/
UINT uCallbackMessage; /*定义消息名称标识符*/
HICON hIcon; /*图标句柄*/
CHAR szTip[64];/*提示串*/
}
在结构NOTIFYICONDATAW中CHAR szTip[64]定义为:
WCHAR szTip[64];
定义NOTIFYICONDATA型变量后,通过Shell-NotifyIcon向其发送消息,以完成图标的建立、删除、修改操作。Shell-NotifyIcon定义在shellapi.h中也有两种形式Shell-NotifyIco nA和Shell-NotifyIconW。其声明如下:
WINSHELLAPI BOOL WINAPI Shell-NotifyIconA(DWORD dwMessage,PNOTIFYICONDATAA lpData);
WINSHELLAPI BOOL WINAPI Shell-NotifyIconW(DWORD dwMessage,PNOTIFYICONDATAW lpData);
其中lpData即指向类型为NOTIFYICONDATA的变量的指针,dwMessage为以下三者之一:
NIM-ADD 增加图标
NIM-MODIFY 修改图标
NIM-DELETE 删除图标
当需要在任务栏增加一个图标时,发送NIM-ADD消息;当需要修改已经存在的图标时,发送NIM-MODIFY消息;当程序退出或相关事件不存在时,发送NIM-DELETE消息。
以下是程序及相关文件清单:
/* program demo.c*/
#include"demo.h"
#include<windowsx.h>
#define MYWM-NOTIFYICON (WM-APP+100)
HINSTANCE hinstance;
BOOL IsExisted=FALSE;/*用于标记图标是否已经显示*/
UINT uNotify=IDC-NOTIFY,uTip=IDC-TIP;
BOOL IconMessage(HWND hDlg,DWORD dwMessage,UINT uID,HICON hIcon,PSTR pszTip)
{BOOL retval;
/*结构NOTIFYICONDATA赋值*/
NOTIFYICONDATA tnd; tnd.cbSize=sizeof(NOTIFYICONDATA);
tnd.hWnd=hDlg; tnd.uID=uID;
tnd.uFlags=NIF-MESSAGE|NIF-ICON|NIF-TIP; tnd.hIcon=hIcon;
tnd.uCallabackMessage=MYWM-NOTIFYICON;
if(pszTip){lstrcpyn(tnd.szTip,pszTip,sizeof(tnd.szTip));}
else{tnd.szTip[0]=‘\0’;}
retval=Shell-NotifyIcon(dwMessage,&tnd);
if(hIcon)DestroyIcon(hIcon);
return retval;
}
LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi)
{HICON hIcon;
hIcon=(HICON)LoadImage(hinstance,MAKEINTRESOURCE(lpdi->CtlID),IMAGE-ICON,16,16,0);
if(!hIcon){return(FALSE);}
DrawIconEx(1pid->hDC,lpdi->rcItem.left,lpdi->rcItem.top,hIcon,16,16,0,NU
LL,DI-NORMAL);
return(TRUE);
}
void IconStateChange(HWND hDlg) /*图标状态改变时调用*/
{ char szTip[64],szIconFilename[128];
if(!GetDlgItemText(hDlg,IDC-ICONFILENAME,szIconFilename,sizeof(szIconFilename)))
{lstrcpyn(szIconFilename,"demo.ico\0",sizeof(szIconFilename));}
if(!GetDlgItemText(hDlg,IDC-TIP,szTip,sizeof(szTip))){*szTip=‘\0’;}
IconMessage(hDlg,NIM-MODIFY,uNotify,LoadImage(hinstance,szIconFilename,I
MAGE-ICON,16,16,LR-LOADFROMFILE),szTip);
}
void IconAdd(HWND hDlg) /*增加图标*/
{IconMessage(hDlg,NIM-ADD,uNotify,NULL,NULL);
IconStateChange(hDlg);IsExisted=TRUE;}
void IconDelete(HWND hDlg) /*删除图标*/
{IconMessage(hDlg,NIM-DELETE,uNotify,NULL,NULL);
IsExisted=FALSE;}
void IconChange(HWND hDlg) /*修改图标*/
{IconMessage(hDlg,NIM-MODIFY,uNotify,NULL,NULL);
IconStateChange(hDlg);IsExisted=TRUE;}
BOOL CALLBACK TestAppDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM1Param)
{switch (uMsg)
{case WM-INITDIALOG:break;
case WM-DRAWITEM:return(IconDrawItem((LPDRAWITEMSTRUCT)1Param));
case WM-DESTROY:IconDelete(hDlg);break;
case WM-COMMAND:
switch (GET-WM-COMMAND-ID(wParam,1Param))
{case IDCANCEL:EndDialog(hDlg,TRUE);break;
case IDC-LOAD:if (IsExisted)IconChange(hDlg);else{IconAdd(hDlg);}
ShowWindow(hDlg,SW-HIDE);break;
case IDC-UNLOAD:IconDelete(hDlg);break;
}
break;
case MYWM-NOTIFYICON:
switch (1Param)
{ /*双击鼠标时激活主窗口*/
case WM-LBUTTONDBLCLK:ShowWindow(hDlg,SW-SHOW);
SetForegroundWindow(hDlg);break;
default:break;
}
break;
default:return(FALSE);
}
treurn(TRUE);
}
#pragma argsused
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR 1pCmdLine,int nCmdShow)
{hinstance=hInstance;
DialogBox(hInstance,MAKEINTRESOURCE(IDD-DEMO),NULL,TestAppDlgProc);
return(FALSE);
}
/* demo.h*/
#define IDC-STATIC -1
#define IDC-LOAD 101
#define IDC-UNLOAD 102
#define IDC-DEMO 103
#define IDC-NOTIFY 104
#define IDC-TIP 201
#define IDC-ICONFILENAME 202
extern HINSTANCE hinstance;
/*资源文件*/
#include "demo.h"
IDD-DEMO DIALOG 0,1,176,63 STYLE DS-MODALFRAME|WS-POPUP|WS-VISIBLE|WS-CAPTION|WS-SYSMENU |WS-MINIMIZEBOX
CAPTION "演示在任务栏放置图标"
FONT 10,"Arial"
{CONTROL "图标文件名",-1,"static",SS-LEFT|WS-CHILD|WS-VISIBLE,16,15,38,8
EDITTEXT IDC-ICONFILENAME,54,13,56,12,ES-AUTOHSCROLL
LTEXT "提示字符串",IDC-STATIC,16,38,36,8
EDITTEXT IDC-TIP,56,36,56,12,ES-AUTOHSCROLL
CONTROL "放置",101,"button",BS-PUSHBUTTON|BS-CENTER|WS-CHILD|WS-VISIBLE|
WS-TABSTOP,125,13,30,14
CONTROL "撤消",102,"button",BS-PUSHBUTTON|BS-CENTER|WS-CHILD|WS-VISIBLE|
WS-TABSTOP,124,36,30,14
}
程序说明:
程序运行后,由用户输入要显示的图标文件名和提示字符串,使用放置按钮在任务栏放置图标,同时隐藏主窗口,使用撤消按钮取消图标显示。
函数IconMessage(HWND hDlg,DWORD dwMessage,UINT,uID,HICON hIcon,PSTR pszTip) 用于向uID指定的图标发送dwMessage消息,hICON为要显示图标的句柄,pszTip为提示字符串。
函数IconDrawItem(LPDRAWITEMSTRUCT lpdi)用于显示图标。
函数IconStateChange(HWND hDlg)用于当状态发生改变时更新图标,如果没有输入图标文件名则使用默认的图标demo.ico。
函数IconAdd(HWND hDlg)、IconDelete(HWND hDlg)、IconChange(HWND hDlg)分别用于增加、删除和修改图标。IsExisted用于判断是否已经有图标显示。双击图标激活主窗口。
以上程序只是演示在Win95上放置图标的方法,有兴趣者可以给程序加上弹出菜单和其它功能来完善程序功能。
- 最新评论
