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

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

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

     //最小化到托盘栏
//第一步,生成一个成员变量,或者一个全局变量
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. Flexbox与Grid属性比较

    网格容器(container)属性 网格项目(item)属性 Flex容器(container)属性 Flex项目(item)属性

  2. ubuntu 16.4 安装配置IK6.3.2

    1. 从官网下载对应的解析版本 https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v6.3.2 2. 配置环境 安装mvn ...

  3. 解决 Unable to convert MySQL date/time value to System.DateTime

    C#读取MySql时,如果存在字段类型为date/datetime时的可能会出现以下问题“Unable to convert MySQL date/time value to System.DateT ...

  4. WQS二分学习笔记

    前言 \(WQS\)二分听起来是个很难的算法,其实学起来也并不是那么难. 适用范围 在某些题目中,会对于某个取得越多越优的物品,限定你最多选择\(k\)个,问你能得到的最优答案. 例如这道题目:[CF ...

  5. SpringBoot学习记录(一)

    一.SpringBoot入门 1.SpringBoot简介 简化Spring应用开发的一个框架:整个Spring技术栈的一个大整合:J2EE开发的一站式解决方案: SpringBoot的优点: (1) ...

  6. N-gram的原理、用途和研究

    N-gram的原理.用途和研究 N-gram的基本原理 转自:http://blog.sciencenet.cn/blog-713101-797384.html N-gram是计算机语言学和概率论范畴 ...

  7. windows下安装win7虚拟机并安装oracle

    一.win7虚拟机 与安装linux虚拟机没有什么不同,不同的是选择客户机操作系统.内存.磁盘容量,以及映像文件. 创建win7虚拟机步骤简化: 新建虚拟机-->>自定义-->> ...

  8. 国产中标麒麟Linux部署dotnet core 环境并运行项目 (一) 安装dotnet core

    背景 根据我之前写的文章 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net Core\Standard项目,我们将公司内部最核心的ORM框架迁移到net core 上面,并在win ...

  9. js中的日期

    创建日期对象: var date1 = new Date(2018, 11,10)  第二个参数传入的是月份,月份是0-11,实际上要加1 获得现在的时间:var date2 = Date.now() ...

  10. 【Python学习之十】yield之send方法

    yield作用 简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator.下面以斐波拉 ...