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

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

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

     //最小化到托盘栏
//第一步,生成一个成员变量,或者一个全局变量
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. 一位学长的学习建议(java方向)

    1.前台总得有个拿的出手的页面能力吧,ajax,jquery不说精通但是至少能看懂,能根据业务需求来改吧. 2.数据库方面至少得玩过mysql,DB2,Oracle中的两个以上吧.hibernate或 ...

  2. 【extjs6学习笔记】0.4 准备: 书籍与文档

    Ext JS 6 By Example Ext JS Essentials Learning Ext JS - Fourth Edition Ext JS 6: Getting Started htt ...

  3. linux下mysql多实例安装(转)

    转自:http://www.cnblogs.com/xuchenliang/p/6843990.html   1.MySQL多实例介绍 1.1.什么是MySQL多实例 MySQL多实例就是在一台机器上 ...

  4. vs移动团队项目集合

    vs移动团队项目集合: https://msdn.microsoft.com/zh-cn/library/vs/alm/dd936138(v=vs.120)/css

  5. winform中获取当前周次

    /*方法一*/ var dt = DateTime.Now; //找到今年的第一天是周几 int firstWeekend = Convert.ToInt32(DateTime.Parse(dt.Ye ...

  6. c++ STL stack容器成员函数

    这是后进先出的栈,成员函数比较简单,因为只能操作栈顶的元素.不提供清除什么的函数. 函数 描述 bool s.empty() 栈是否为空(即size=0).若空,返回true,否则,false. vo ...

  7. Hbase各种查询总结

    运用hbase好长时间了,今天利用闲暇时间把Hbase的各种查询总结下,以后有时间把协处理器和自定义File总结下. 查询条件分为: 1.统计表数据 2,hbase 简单分页 3,like 查询 4  ...

  8. 破解 D-H 协议

    756: 破解 D-H 协议 时间限制: 1 Sec  内存限制: 128 MB提交: 78  解决: 18[提交] [状态] [讨论版] [命题人:admin] 题目描述 Diffie-Hellma ...

  9. 2018.2.6 JS-判断用户浏览器

    JS-判断用户浏览器 在判断用户使用的浏览器是否为PC还是移动设备,有时候项目中需要用到.可在需要的项目中当全局方法来使用. 判断代码 function getMoblieDevice(window) ...

  10. Java - 通过私有构造方法获取实例