有关托盘编程的基础知识呢,也就上面这些了。下面呢,我们就进入具体的实战演练阶段,举几个托盘编程的例子瞧瞧,加深理解。

  1、将程序最小化到系统托盘区的函数toTray()。

void CTimeWakeDlg::toTray()
{
NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;
nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称
nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(nid.szTip,"计划任务提醒");//信息提示条为“计划任务提醒”
Shell_NotifyIcon(NIM_ADD,&nid);//在托盘区添加图标
ShowWindow(SW_HIDE);//隐藏主窗口
}

  这是个很简单的函数,里面首先给NOTIFYICONDATA赋值,然后调用shell_NotifyIcon, 头一个参数是NIM_ADD,表示添加。然后用函数ShowWindow 隐藏主窗口,这样,就实现了将程序最小化到系统托盘区的任务了。

  2、程序已经最小化到托盘区了,但是呢,对托盘图标的操作如何进行呢?这就体现了结构NOTIFYICONDATA的成员uCallbackMessage 的作用了。它所提供的作用就是,当用户用鼠标点击托盘区的图标的时候(无论是左键还是右键),会向hWnd所代表的窗口传送消息,如果是上例,消息的名称就是WM_SHOWTASK。根据VC的消息机制,对自定义消息增加消息响应函数。

  在头文件的//{{AFX_MSG和//}}AFX_MSG之间声明消息响应函数:

  afx_msg LRESULT onShowTask(WPARAM wParam,LPARAM lParam);

  然后在CPP文件中添加消息映射。在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP 之间加入: ON_MESSAGE(WM_SHOWTASK,onShowTask)将消息和消息响应函数映射起来。

  然后就是在CPP文件中加入函数onShowTask的实现了:

LRESULT CTimeWakeDlg::onShowTask(WPARAM wParam,LPARAM lParam)
//wParam接收的是图标的ID,而lParam接收的是鼠标的行为
{
if(wParam!=IDR_MAINFRAME)
return 1;
switch(lParam)
{
case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“关闭”
{

LPPOINT lpoint=new tagPOINT;
::GetCursorPos(lpoint);//得到鼠标位置
CMenu menu;
menu.CreatePopupMenu();//声明一个弹出式菜单
//增加菜单项“关闭”,点击则发送消息WM_DESTROY给主窗口(已
//隐藏),将程序结束。
menu.AppendMenu(MF_STRING,WM_DESTROY,"关闭");
//确定弹出式菜单的位置
menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
//资源回收
HMENU hmenu=menu.Detach();
menu.DestroyMenu();
delete lpoint;
}
break;
case WM_LBUTTONDBLCLK://双击左键的处理
{
this->ShowWindow(SW_SHOW);//简单的显示主窗口完事儿
}
break;
}
return 0;
}


------------------------------------

http://www.daima.com.cn/Info/38/Info6881/

1。对不同的消息,MFC用不同的宏实现消息映射
2。消息映射表处理这个类所定义的消息映射和这个类不处理而定义的消息而传递给其父类处理的消息映射
3。在BEGIN_...和END_...之间的宏为这个消息映射表必须处理的消息产生登录入口
4。宏分类:
    1、标准WINDOWS消息都由宏ON_WM_XXX处理,其中XXX为标准消息名
    2、宏ON_REGISTERED_MESSAGE用于处理用户自己登记注册的WINDOWS窗口消息。
    这个宏接受NEAR类型的无符号整型变量,这个变量就是已经登记注册的WINDOWS消息标识。
该消息标识可由RegisterWindowMessage函数调用而得到系统唯一的全局消息。
例如:afx_msg LRESULT OnFind(WPARAM wParam,LPARAM lParam);
static UINT NEAR WM_FIND=RegisterWindowMessage("COMMONDLG_FIND"); //用此函数登记的消息范围是0XC000~0XFFFF
( 注: WM_FIND必须说明为NEAR类型 )
BEGIN_MESSAGE_MAP(...)
...
ON_REGISTERED_MESSAGE(WM_FIND,OnFind)
...
END_MESSAGE_MAP
3、用户自定义的WINDOWS消息可以用宏ON_MESSAGE包含在消息映射中
#define WM_MYMESSAGE WM_USER+100
ON_MESSAGE(WM_MYMESSAGE,OnMymessage)
可以通过: CWnd * pwnd=...; pwnd->SendMessage(WM_MYMESSAGE);来实现
4、命令消息的处理是使用宏ON_COMMAND,命令消息包括菜单命令和菜单加速键命令,格式为ON_COMMAND(ID,MEMBERFUNCTION)
ON_COMMAND接受命令标识,实际的命令处理函数不带任何参数,处理完后也不返回任何类型值
5、命令更新的消息与ON_COMMAND的处理的机制的方法相同,
不同的使用宏ON_UPDATE_COMMAND_UI来代替宏ON_COMMAND的使用。
格式为:ON_UPDATE_COMMAND_UI(ID,MEMBERFUNCTION).
此成员处理函数带一个参数CCmdUI * cmdUI,但不返回任何值.
6、ON_COMMAND_EX不仅包含所有ON_COMMAND功能,而且提供了宏的功 能超集.
扩展后的命令处理成员函数仅仅带有一个参数,一个包含命令标识符的无符号整型数,
函数要求返回一个布尔型值,如果返回为正,则表示消息已经处理,
为假,表示这个命令消息还要传给其他命令处理函数进一步处理 。
7、更高级的消息宏还有ON_COMMAND_RANGE、ON_COMMAND_RANGE_EX,
这两个宏允许用一个命令处理器处理属于一定范围的命令消息。
CLASSWIZARD 仅仅识别ON_COMMAND、ON_UPDATE_COMMAND_UI宏
8、对于一个窗口的子控制送往这个窗口的通知消息来说,
这个通知消息在消息映射表之中有一个额外的信息:子控制的标识。
仅当在消息映射表中的消息处理函数满足两个条件时,它才被调用。
(a). 子控制的通知消息代码,即LPARAM的高字节; (b).子控制的标识
(即WPARAM)与消息映射表中的子控制标识相同
9、用户自定义的消息通知码可以用宏ON_CONTROL在消息映射表中,
定义用户自己的消息通知码处理函数.定义格式为:
ON_CONTROL(WNOTIFICATIONCODE,ID,MEMBERFUNCTION)
10、可以采用宏ON_CONTROL_RANGE处理一定范围内的子控制通知消息码
11、对于复杂的WINDOWS控制通知消息,WINDOWS的公用控制利用了更加强大的WM_NOTIFY
在CWnd类中,成员函数OnNotify用于处理子控制的通知消息,一般的没有必要重载此函数
定义格式为ON_NOTIFY(WNOTIFICATIONCODE,ID,MEMBERFUNCTION)
成员函数的定义格式:afx_msg void memberfunction(NMHDR *pNotifyStruct,LRESULT *result)
pNotifyStruct 为指向通知消息结构的指针,result为指向返回结果的指针

--------------------------------------

综合例子:

#define WM_SHOW_TASK WM_USER+150 //这个是自定义的一消息,用来传递mouse点到拖盘区的信息

。。。

BEGIN_MESSAGE_MAP(CMynetsendDlg, CDialog)
//{{AFX_MSG_MAP(CMynetsendDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_MESSAGE(WM_SHOW_TASK,OnShowTask)
ON_WM_SHOWWINDOW()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

。。。

void CMynetsendDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}

if (nID==SC_MINIMIZE)
{

NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;
nid.uCallbackMessage=WM_SHOW_TASK;//自定义的在托盘区显示图标的消息
nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(nid.szTip,"要发消息点我!");//信息提示条
Shell_NotifyIcon(NIM_ADD,&nid);//在托盘区添加图标
ShowWindow(SW_HIDE);//隐藏窗口

}

}

LRESULT CMynetsendDlg::OnShowTask(WPARAM wParam,LPARAM lParam)
//wParam接收的是图标的ID,而lParam接收的是鼠标的行为
{ 
if(wParam!=IDR_MAINFRAME) return 1;

switch(lParam)
{
case WM_RBUTTONUP://右键起来时弹出快捷菜单
{   
   LPPOINT lpoint=new tagPOINT;
   ::GetCursorPos(lpoint);//得到鼠标位置

   CMenu menu;
   int pMenuID = 0;

   VERIFY(menu.LoadMenu(IDR_MENU1));//得到菜单
   CMenu* pPopup = menu.GetSubMenu(pMenuID);//得到子菜单
   ASSERT(pPopup != NULL);
   
   DWORD Made = pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,lpoint->x,lpoint->y,this,NULL);//使用子菜单
   
   switch(Made)
   {
   case ID_MENUITEM32771: {DestroyWindow();} break;
   case ID_MENUITEM32772: {ShowWindow(SW_SHOW);ShowWindow(SW_SHOWNORMAL);} break; 
   case ID_MENUITEM32773: {CAboutDlg dlgAbout;dlgAbout.DoModal();} break; 
   }

   pPopup->DestroyMenu();
   HMENU hmenu=menu.Detach();//资源回收
   menu.DestroyMenu();
   delete lpoint;
}

break;
case WM_LBUTTONDOWN://左键的处理
{

   ShowWindow(SW_SHOW); //简单的显示主窗口完事儿
   ShowWindow(SW_SHOWNORMAL); //可以避免原来的最小化
}
break;
}
return 0;
}

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zgbsoap/archive/2006/03/24/636630.aspx

posted on 2011-02-20 16:03  °ι 、曲 终  阅读(353)  评论(0编辑  收藏  举报