MFC定时关机程序的实现3-最小化到托盘栏
这个定时关机运行过后默认最小化到托盘栏最好了,不用每次都去点了。
现在来看看如何将程序显示在托盘栏。
首先在头文件里声明一个变量和一个消息响应函数
//最小化到托盘栏
//第一步,生成一个成员变量,或者一个全局变量
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-最小化到托盘栏的更多相关文章
- 将VMware虚拟机最小化到托盘栏
版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可. 目录 前言 将VMware最小化到托盘栏的方法 1.下载 Trayconizer 2.解压 trayco ...
- 将VMware工作站最小化到托盘栏
目录 前言 将VMware最小化到托盘栏的方法 1.下载 Trayconizer 2.解压 trayconizerw.zip 3.创建 VMware 快捷方式 4.修改 VMware 快捷方式 5.运 ...
- MFC定时关机程序的实现1
写个定时关机程序自用,界面简单实用,最终界面如下 第一步,新建一个MFC对话框应用程序,拖几个控件过来, 界面如下: 然后给下拉列表框,复选按钮绑定变量,以方便进行操作. CComboBox m_co ...
- MFC定时关机程序的实现2-添加启动项到注册表
虽然上一篇实现了的定时关机,但是还不够完善,比如开机自动启动,然后按照配置的时间定时关机,并最小化到任务栏. 先来说开机启动怎么实现,开机启动实现的方法有好几种,比如直接在开始菜单启动项里添加一个程序 ...
- C# 程序启动最小化至任务栏及闪烁
主要功能: C#让窗体最小化至任务栏,同时在系统托盘区的图标点击左键能显示窗体,并使窗体闪烁. 首先: 创建窗体应用程序,并添加控件NotifyIcon及ContextMenuStrip控件 Noti ...
- VC最小化到托盘程序
在实际操作电脑的过程中,我们常常可以看到一些应用程序可以最小化到桌面右下角的托盘中显示,如一些杀毒软件等开机就显示在托盘中,或是我们常用的QQ等聊天工具,都可以最小化在托盘中,如图-1. 在图-1中, ...
- delphi如何让程序最小化到任务栏(转)
现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标.象FoxMail 3.0 NetVampire 3.0等都提供了这样的功 ...
- Delphi如何让程序最小化到任务栏(截取WM_SYSCOMMAND后,调用Shell_NotifyIcon)
现在很多的应用程序都有这样一种功能,当用户选择最小化窗口时,窗口不是象平常那样最小化到任务栏上,而是“最小化”成一个任务栏图标.象FoxMail 3.0 NetVampire 3.0等都提供了这样的功 ...
- C# 设置程序最小化到任务栏右下角,鼠标左键单击还原,右键提示关闭程序
首先设置程序最小化到任务栏右下角 先给窗口添加一个notifyIcon控件 为notifyIcon控件设置ICO图标(不设置图标将无法在任务栏显示) 给notifyIcon控件添加点击事件 然后是最小 ...
随机推荐
- Ubuntu 16.04 远程登入root 用户
安装 open ssh: sudo apt-get install openssh-server 修改 root 密码 sudo passwd root 以其他账户登录,通过 sudo nan ...
- Masonry 等间隔或等宽高排列多个控件
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...
- Kyligence Analytics Platform Enterprise
平台: arm 类型: ARM 模板 软件包: kap 2.3 kyanalyzer 2.3 apache kylin basic software bi big data cube data war ...
- Android(java)学习笔记74:ListViewProject案例(ListView + ArrayAdapter)
1. 首先是MainActivity.java文件,如下: package com.himi.lv1; import java.util.ArrayList; import java.util.Lis ...
- 浅谈 import / export
import { ngModule } from '@angular/core'; import { AppComponent } from './app.component'; export cla ...
- 站点安全预警,建议大家多重禁止load_file函数!
比如在你的linux机器上运行 select load_file(0x2F6574632F706173737764); 看看结果是什么?这应该不是我们希望看到的. 所以我们禁用这个函数吧. 这个主要通 ...
- 2018.5.19 Oracle数据操作和管理表的综合练习
--作业一.使用自己的用户登录,完成如下操作,并且创建5条测试数据 -- 创建学生表(stu),字段如下: -- 学号(stuID) -- 姓名(stuName) -- 性别(stuSex) -- 入 ...
- python剑指offer 包含min函数的栈
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1)). # -*- coding:utf-8 -*- class Solution: def ...
- JDBC开发,数据库的连接
JDBC开发步骤 1.建完工程后,右击工程,new,新建一个文件夹Folder,装jar包, 2.将下载好的驱动包打开,找到jar文件,CTRL+C,选中装jar包的文件夹,CTRL+V ...
- let和const在es6中的异同点
let和const这两个都是声明一个变量或函数的方法与var差不太多的效果 let的声明在for循环中,当你定义的是多少,最后你的值就是多少开始的,它只进行一次循环,不会像var那样去一遍一遍的去遍历 ...