这个定时关机运行过后默认最小化到托盘栏最好了,不用每次都去点了。

现在来看看如何将程序显示在托盘栏。

首先在头文件里声明一个变量和一个消息响应函数

     //最小化到托盘栏
//第一步,生成一个成员变量,或者一个全局变量
NOTIFYICONDATA m_NOTIFYICON;
//第二步,添加自定义消息响应函数
afx_msg LRESULT OnNotifyIcon(WPARAM wParam,LPARAM lParam);

然后初始化消息相关的参数

//第三步,添加消息标识
#define WM_NC WM_USER + 1001

现在添加消息映射

//第四步,添加消息映射
ON_MESSAGE(WM_NC, &OnNotifyIcon)

最后定义消息响应函数,这里主要是做一些相应鼠标操作,比如左键单击,右键单击等的事件

LRESULT CAutoShutDownDlg::OnNotifyIcon(WPARAM wParam,LPARAM lParam)
{
////最小化图标,,wParam接收的是图标的ID,而lParam接收的是鼠标的行为
if (wParam == IDI_ICON1)
{
return ;
}
switch(lParam)
{
case WM_LBUTTONDOWN:
{
//鼠标单击图标时的动作
if (AfxGetApp()->m_pMainWnd->IsWindowVisible())//判断窗口当前状态
{
//窗口未最小化
AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE);
}
else
{
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW);
}
}
break;
case WM_RBUTTONUP:
{
////右键起来时弹出快捷菜单,这里只有一个“关闭”
LPPOINT lp = new tagPOINT;//鼠标位置结构
::GetCursorPos(lp);//获得鼠标位置
CMenu menu;
menu.CreatePopupMenu();//声明一个弹出式菜单
//增加菜单项“退出”,点击则发送消息WM_DESTROY给主窗口(已隐藏),将程序结束。
menu.AppendMenu(MF_STRING,WM_DESTROY,"退出");
menu.TrackPopupMenu(TPM_LEFTALIGN,lp->x,lp->y,this);
//资源回收
HMENU hmenu = menu.Detach();
menu.DestroyMenu();
delete lp;
}
break;
default:
break;
}
return ;
}

这些操作完成后还要有一个初始化操作OnInitDialog()

    //最小化到托盘代码初始化
m_NOTIFYICON.cbSize = sizeof(NOTIFYICONDATA);//这个是必须的,指定结构大小
m_NOTIFYICON.hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);//指定在托盘显示的图标,这个图标可以自己导入
m_NOTIFYICON.hWnd = m_hWnd;//指定窗口句柄
m_NOTIFYICON.uID = IDR_MAINFRAME;//托盘图标ID
m_NOTIFYICON.uCallbackMessage = WM_NC;//自定义的消息函数
lstrcpy(m_NOTIFYICON.szTip,"定时关机");//在托盘栏显示的提示信息
m_NOTIFYICON.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;//
Shell_NotifyIcon(NIM_ADD,&m_NOTIFYICON);//在托盘显示图标

最后一点就是在程序退出时销毁图标

     //退出程序时销毁图标
Shell_NotifyIcon(NIM_DELETE,&m_NOTIFYICON);//

这里面用到了一个结构  NOTIFYICONDATA

 typedef struct _NOTIFYICONDATA {
DWORD cbSize; // 结构的大小,必须在程序中给出
HWND hWnd; // 程序中将要接收托盘消息的窗口句柄
UINT uID; // 应用程序中定义的托盘图标ID,此参数用作标识
UINT uFlags;  //设置属性 标记下边3个参数是否有效
UINT uCallbackMessage;// 自定义的消息ID值
HICON hIcon;//显示在系统托盘上的Icon的句柄
#if (_WIN32_IE < 0x0500)
TCHAR szTip[;// 用于图标显示的提示字符串
#else
TCHAR szTip[];
#endif
#if (_WIN32_IE >= 0x0500)
DWORD dwState;
DWORD dwStateMask;
TCHAR szInfo[];
union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
TCHAR szInfoTitle[];
DWORD dwInfoFlags;
#endif
#if (_WIN32_IE >= 0x600)
GUID guidItem;
#endif
} NOTIFYICONDATA, *PNOTIFYICONDATA;

后面的一些参数默认就好,不要配置

还有一点就是怎么保证程序只有一个进程在运行

 有两种方法可以实现,第一通过全局互斥变量,第二通过查找窗口名

  第一,全局互斥变量

  在应用程序类中声明一个全局变量

     HANDLE hMutex;

  然后在应InitInstance()函数中添加如下代码

     hMutex = ::CreateMutex(NULL,TRUE,"FIRSTDLG");
if(hMutex != NULL)
{
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
AfxMessageBox("已经有一个程序在运行了");
exit();
}
}

  第二,findwindow函数实现

  添加一个成员函数,函数定义如下,只需要在初始化时判断一下就行了

 BOOL CAutoShutDownApp::FirstInstance()
{
CWnd *pWndPrev, *pWndChild; // 通过窗口标题查找窗口是否已经打开。成功则返回指向窗口的句柄,否则为NULL
pWndPrev = CWnd::FindWindow(NULL, "定时关机");
if (NULL != pWndPrev)
{
// 存在这个窗口,获取上一次的状态
pWndChild = pWndPrev->GetLastActivePopup(); // 是否最小化了,还原
if (pWndPrev->IsIconic())
pWndPrev->ShowWindow(SW_RESTORE); //显示到最上层
pWndChild->SetForegroundWindow(); return FALSE;
} return TRUE;
}

  在初始化时进行查找,在InitInstance()函数里添加如下代码

if (!FirstInstance())
{
return FALSE;
}

当然还有其他方法,不过这两种比较简单。

FindWindow()函数定义如下,两个参数必须至少有一个有效
 static CWnd* PASCAL FindWindow(
LPCTSTR lpszClassName,//窗口类名
LPCTSTR lpszWindowName //窗口标题
);//

还有一个问题要说的,就是程序启动后自动隐藏的情况,原来是想着直接在里面ShowWindow(SWP_HIDE);来实现的,不过很遗憾这条语句根本不起作用,因为窗口的现实是在初始化之后的某个地方显示的。

GetWindowPlacement,SetWindowPlacement这两个函数可以实现这个功能。

过程如下,首先我们需要一个成员变量来保存这个窗口的一些配置信息。

  WINDOWPLACEMENT m_wp;

在OnInitDialog中进行初始化

 //程序启动后自动隐藏到托盘栏
GetWindowPlacement(&m_wp); //恢复时用
ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);//从任务栏中去掉. WINDOWPLACEMENT wp;//声明结构
wp.length=sizeof(WINDOWPLACEMENT);//制定大小
wp.flags=WPF_RESTORETOMAXIMIZED;//标志
wp.showCmd=SW_HIDE;//状态
SetWindowPlacement(&wp);//设置隐藏

然后在OnNotifyIcon()函数中进行鼠标相应

 LRESULT CAutoShutDownDlg::OnNotifyIcon(WPARAM wParam,LPARAM lParam)
{
////最小化图标,,wParam接收的是图标的ID,而lParam接收的是鼠标的行为
if (wParam == IDI_ICON1)
{
return ;
}
switch(lParam)
{
case WM_LBUTTONDOWN:
{
//鼠标单击图标时的动作
if (AfxGetApp()->m_pMainWnd->IsWindowVisible())//判断窗口当前状态
{
//窗口未最小化
AfxGetApp()->m_pMainWnd->ShowWindow(SW_HIDE);
}
else
{
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOW); m_wp.length=sizeof(WINDOWPLACEMENT);
23 m_wp.flags=WPF_RESTORETOMAXIMIZED;
24 m_wp.showCmd=SW_SHOW;
25 SetWindowPlacement(&m_wp);
// 在这里恢复显示状态
} }
break;
case WM_RBUTTONUP: ............................. }

现在可以实现启动后隐藏了,但是还有一个问题那就左键单击图标后,窗口显示在最上层了,但是标题栏却是未激活状态,没有重绘。所以接下来添加一个重绘框架函数

OnNcPaint()

void CAutoShutDownDlg::OnNcPaint()
{
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialogEx::OnNcPaint()
static int i = ;
if (i>)
{
i--;
ShowWindow(SW_HIDE);
}
else
CDialogEx::OnNcPaint(); }

到现在基本完成了。

这里是源代码,这个博客园的文件上传貌似不太好用,就用百度云了,运行环境是vs2010+win7 64位

http://pan.baidu.com/s/1i35gqET

MFC定时关机程序的实现3-最小化到托盘栏的更多相关文章

  1. 将VMware虚拟机最小化到托盘栏

    版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可.   目录 前言 将VMware最小化到托盘栏的方法 1.下载 Trayconizer 2.解压 trayco ...

  2. 将VMware工作站最小化到托盘栏

    目录 前言 将VMware最小化到托盘栏的方法 1.下载 Trayconizer 2.解压 trayconizerw.zip 3.创建 VMware 快捷方式 4.修改 VMware 快捷方式 5.运 ...

  3. MFC定时关机程序的实现1

    写个定时关机程序自用,界面简单实用,最终界面如下 第一步,新建一个MFC对话框应用程序,拖几个控件过来, 界面如下: 然后给下拉列表框,复选按钮绑定变量,以方便进行操作. CComboBox m_co ...

  4. MFC定时关机程序的实现2-添加启动项到注册表

    虽然上一篇实现了的定时关机,但是还不够完善,比如开机自动启动,然后按照配置的时间定时关机,并最小化到任务栏. 先来说开机启动怎么实现,开机启动实现的方法有好几种,比如直接在开始菜单启动项里添加一个程序 ...

  5. C# 程序启动最小化至任务栏及闪烁

    主要功能: C#让窗体最小化至任务栏,同时在系统托盘区的图标点击左键能显示窗体,并使窗体闪烁. 首先: 创建窗体应用程序,并添加控件NotifyIcon及ContextMenuStrip控件 Noti ...

  6. VC最小化到托盘程序

    在实际操作电脑的过程中,我们常常可以看到一些应用程序可以最小化到桌面右下角的托盘中显示,如一些杀毒软件等开机就显示在托盘中,或是我们常用的QQ等聊天工具,都可以最小化在托盘中,如图-1. 在图-1中, ...

  7. delphi如何让程序最小化到任务栏(转)

    现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标.象FoxMail 3.0 NetVampire 3.0等都提供了这样的功 ...

  8. Delphi如何让程序最小化到任务栏(截取WM_SYSCOMMAND后,调用Shell_NotifyIcon)

    现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标.象FoxMail 3.0 NetVampire 3.0等都提供了这样的功 ...

  9. C# 设置程序最小化到任务栏右下角,鼠标左键单击还原,右键提示关闭程序

    首先设置程序最小化到任务栏右下角 先给窗口添加一个notifyIcon控件 为notifyIcon控件设置ICO图标(不设置图标将无法在任务栏显示) 给notifyIcon控件添加点击事件 然后是最小 ...

随机推荐

  1. Android在应用设置里关闭权限,返回生命周期处理

    问题 在处理6.0运行时权限时,很多人都忽略了这样一个问题: 在一个App应用里,如果已经允许了一个权限比如(读取通讯权限),此刻去调用相机,弹出权限申请对话框,此刻点击拒绝,然后经过处理后弹出去设置 ...

  2. java 千分位的添加和去除

    转至:http://blog.sina.com.cn/s/blog_8f99a1640102v1xh.html 将一个数字转换为有千分位的格式: NumberFormat numberFormat1  ...

  3. HDU1664 BFS + 数论 + 剪枝

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1664 , 一道比较蛋疼的搜索题. 这道题有很多坑点,一点处理不好就要TLE. 题意很简单,就是找到一个 ...

  4. java Vamei快速教程21 事件响应

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在GUI中,我们看到了如何用图形树来组织一个图形界面.然而,这样的图形界面是静态的 ...

  5. Google Guava入门(一)

    Guava作为Java编程的助手,可以提升开发效率,对Guava设计思想的学习则极大的有益于今后的编程之路.故在此对<Getting Started with Google Guava>一 ...

  6. softmax 函数

    总结为:   将一组数变换为  总和为1,各个数为0~1之间的软性归一化结果. ========================================================= 关于 ...

  7. PageHelper 记录总条数不正确问题处理

    //PageHelper.startPage会返回一个page对象,这个对象在查询结果出来后会把页数,记录总数给page对象,用page.getPages()和getTotal()获取页数和记录总数. ...

  8. pandas 常用统计方法

    统计方法 pandas 对象有一些统计方法.它们大部分都属于约简和汇总统计,用于从 Series 中提取单个值,或从 DataFrame 的行或列中提取一个 Series. 比如 DataFrame. ...

  9. IDEA搭建Maven 的聚合项目

    今天突然想把自己学习在eclipse上的maven聚合项目搭建到IDEA上,结果IDEA有太多的配置步骤,导致失败了很多次,终于在网上找到了一篇博客 https://blog.csdn.net/for ...

  10. 数据结构期末复习( はち)--VOA图关键路径求法

    题目如下图: 注:将123456当成abcdef. 事件最早发生事件求法:找从原点到该事件的最长路径(从前往后推) 对a:Ve=0 对b:Ve=max{ 2 , 15+4 }=19 对c:Ve=15 ...