mfc小工具开发之定时闹钟之---时间获取和音频播放
1.这里的音频文件是指*.wav格式的音频,参考了飞雪的音频文件,版本号:
http://www.piaodown.com/down/soft/18512.htm
在此表示感谢,播放函数接口如下
一、使用PlaySound()函数
该函数的原型的是:
BOOL PlaySound(
LPCSTR pszSound,
HMODULE hmod,
DWORD fdwSound
)
其中,参数pszSound指定要播放文件的文件名,若该参数为NULL,则停止正在播放的声音;
参数hmod说明资源的句柄;
参数fdwSound则指定该命令的标志,也就是说明播放WAV文件的方式,可以取以下值:
标志 |
说明 |
SND_ASYNC |
异步播放声音 |
SND_SYNC |
同步播放声音(默认) |
SND_NODEFAULT |
若pszSound指定的文件找不到,不使用默认声音 |
SND_MEMORY |
pszSound指向的一个内存文件 |
SND_LOOP |
循环播放声音,直到下一次调用PlaySound()且pszSound参数为NULL,此标志要与SND_ASYNC一起使用 |
SND_NOSTOP |
不停止当前正在播放的任何声音 |
SND_RESOURCE |
表示pszSound是一个资源的标识符,而hmod则是包含这个资源的一个实例 |
SND_FILENAME |
表示pszSound是一个文件名 |
SND_ALIAS_ID |
表示pszSound预定义的声音标识符 |
SND_ALIAS |
pszSound参数是在注册表或win.ini中定义的一个系统事件,不可与SND_FILENAME或 SND_RESOURCE同时使用。 |
SND_NOWAIT |
如果设备正忙,则立即返回而不播放指定的声音 |
例:
//播放call2.wav
PlaySound("call2.wav",NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);
//关闭声音
PlaySound(NULL,NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);
二、使用sndPlaySound()函数
该函数的原型的是:
BOOL sndPlaySound(
LPCSTR lpszSound,
UINT fuSound
)
其中,参数lpszSound指定要播放的文件名,若为NULL,则停止正在播放的声音
参数fuSound指定播放的方式,可取以下值:
SND_ASYNC,SND_SYNC,SND_LOOP,SND_MEMORY,SND_DODEFAULT,SND_NOSTOP
各个标志的含义同上。
例:
//播放call1.wav
sndPlaySound("call1.wav",SND_ASYNC | SND_LOOP);
//关闭声音
sndPlaySound(NULL,SND_ASYNC | SND_LOOP);
以上两个函数使用简洁、方便,但有两个缺陷,即:
(1) 整个声音必须放入可用的物理内存中,因此,当文件大小小于100K时使用这两个函数,而在大
于100K时,一般使用MCI方式
(2) 该声音用的必须是已安装的音频驱动程序之一所支持的数据格式。
三、使用MCI命令
使用MCI命令实际上也就是利用以下几个相关的API函数完成播放声音的功能:
mciSendCommand() //向MCI设备发送命令消息
mciSendString() //向MCI设备发送命令字符串
mciGetErrorString() //获取MCI函数的返回值的文本描述信息
1. mciSendCommand()函数
函数原型:
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice,
UINT uMsg,
DWORD fdwCommand,
DWORD_PTR dwParam
);
其中,参数IDDevice是接收命令消息的MCI设备的标识,该参数不与命令消息MCI_OPEN同时使用
参数uMsg是命令消息。具体信息可参考MSDN。
参数fdwCommand用来设置命令消息的标志
参数dwParam指向一个包含命令消息参数的结构体
若函数执行成功返回值为0,否则为错误代码。错误信息可用mciGetErrorString()函数得到。
例:
/******************************
打开音频设备
*******************************/
MCI_OPEN_PARMS mciOpenParms;
DWORD dwResult;
mciOpenParms.lpstrDeviceType=(LPSTR)MCI_DEVTYPE_WAVEFORM_AUDIO;
dwResult=mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_WAIT,(DWORD)(LPVOID)&mciOpenParms);
/******************************
关闭音频设备
*******************************/
mciSendCommand(m_nDeviceID,MCI_CLOSE,NULL,NULL);
/****************************
播放WAV文件
****************************/
MCI_OPEN_PARMS mciOpenParms;
memset(&mciOpenParms,0,sizeof(MCI_OPEN_PARMS));
//设置要播放的WAV文件名
mciOpenParms.lpstrElementName=pFileName;
//打开WAV文件
DWORD dwResult=mciSendCommand(m_nDeviceID,MCI_OPEN,MCI_OPEN_ELEMENT,(DWORD)(LPVOID)&mciOpenParms);
2. mciSendString()函数
函数原型:
MCIERROR mciSendString(
LPCTSTR lpszCommand,
LPTSTR lpszReturnString,
UINT cchReturn,
HANDLE hwndCallback
);
其中,参数lpszCommand是一个以'\0'结尾的命令字符串,相关字符串与mciSendCommand()函数中参数uMsg的消息相对应,详见
MSDN
参数lpszReturnString指向一个用来存储返回信息的缓冲区。若不需要返回信息,可设为NULL
参数cchReturn是用来存储返回信息的lpszReturnString的字节数
若在命令字符串中指定了"notify"(通告),则参数hwndCallback指向一个回调窗口。
返回值与mciSendCommand()函数相似
3. mciGetErrorString()函数
函数原型:
BOOL mciGetErrorString(
DWORD fdwError,
LPTSTR lpszErrorText,
UINT cchErrorText
);
其中,参数fdwError是mciSendCommand()函数或mciSendString()函数返回的错误码
参数lpszErrorText指向一个缓冲区,该缓冲区接收一个以'\0'结尾的错误描述字符串
参数cchErrorText用来存储返回信息的lpszErrorText的字节数
例:
char szErrorMsg[MAXERRORLENGTH];
//获取错误描述信息
if(!mciGetErrorString(dwError,szErrorMsg,sizeof(szErrorMsg)))
strcpy(szErrorMsg,"Unknown Error!");
另外,需要注意的是:要包含一个头文件"Mmsystem.h",在链接的时候也要使用一个库文件"Winmm.lib"
http://blog.163.com/baansss0624@126/blog/static/55578661200822111632521/
2.时间获取
MFC获取当前时间
windows相关 2009-10-05 23:22:16 阅读222 评论0 字号:大中小
一、使用MFC可以用以下代码得到
CTime time = CTime::GetCurrentTime(); ///构造CTime对象
int m_nYear = time.GetYear(); ///年
int m_nMonth = time.GetMonth(); ///月
int m_nDay = time.GetDay(); ///日
int m_nHour = time.GetHour(); ///小时
int m_nMinute = time.GetMinute(); ///分钟
int m_nSecond = time.GetSecond(); ///秒
我们还可以用CTime::Format函数将CTime对象转换为字符串对象
例如:
CString m_strTime = time.Format("%Y-%m-%d %H:%M:%S");
运行结果:m_strTime为 2001-8-1 12:11:05
二、使用GetSystemTime()这个API函数得到系统时间
SYSTEMTIME ti;
GetSystemTime(&ti);
////我们可以通过读取SYSTEMTIME结构体成员直接得到时间
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
例如:ti.wMilliseconds;可以得到毫秒时间
以下是转载的:CTime以及其它时间差
一、DateTimePicker控件
引用一个DateTimePicker控件,关联变量m_date为DateTimeCtrl类型,然后在响应事件中加入如下代码:
CTime tm;
m_date.GetTime(tm);
CString strDate=tm.Format("%Y-%m-%d");
就可以获取了...但是不知为何这个还和Vc的版本问题有关,开始时候我用的版本总是出错,或者srtDate为空,或者不是用户选择的日期,后来换了一个VC版本就能得到正确的数据了...
另外如果关联一个CTime类型的变量也能解决上面的问题,但是初始化的日期是1970-01-01而上面方法中初始化的日期是当前日期...所以根据用户需要的设定可以选择任何一种方法进行解决...
二、CTimeSpan获取时间差
要获取两个时间差,如两个CTime的时间差,可以使用MFC中的CTimeSpan类。
CTime time1 = CTime::GetCurrentTime(); ...其它代码... CTime time2 = CTime::GetCurrentTime(); // 两个CTime相减得到CTimeSpan CTimeSpan timeSpan = time2 - time1; // 得到总的秒数 int nTSeconds = timeSpan.GetTotalSeconds();
注意GetTotalSeconds与GetSeconds的区别:GetTotalSeconds返回总的秒数,GetSeconds返回总是小于60,如:如果时间经过了100秒, GetTotalSeconds返回100,而GetSeconds返回40,因为有60秒转为一分钟了,同时使用GetMinutes会返回1,即1分40秒。
其它类似函数:
GetDays(); // 返回日数 GetHours(); // 返回小时数(-23至23之间) GetTotalHours(); // 返回总的小时数 GetMinutes(); // 返回分钟数(-59至59之间) GetTotalMinutes(); // 返回总的分钟数 GetSeconds(); // 返回秒数(-59至59之间) GetTotalSeconds(); // 返回总的秒数 三、CTime总结
1.初始化
m_begintime=CTime(2004,1,1,0,0,0,-1);//参数依次为year,month,day,hour,minite,second
m_endtime =CTime::GetCurrentTime();//当前时间
2.日期比较
CTimeSpan span;
span=time1-time2;
得到两时间的间隔.
可以取得span.GetHours().等
3.access数据库查询
使用DateDiff()函数,具体参照access帮助
CString timesql;
timesql.Format(" Where DateDiff('d',%s,'%s')<=0","日期",m_begintime.Format("%Y-%m-%d")); 4读取日期字段(odbc)
CDBVariant var;
recset.GetFieldValue(i,var);
s.Format("%d-%d-%d",(var.m_pdate)->year,(var.m_pdate)->month,
(var.m_pdate)->day);
5.CTime转换为CString
例:
m_begintime.Format("%Y-%m-%d");//2004-10-03 6.CString转换为CTime
//s="2004-10-5"
int first=s.Find('-');
int second=s.Find('-',first+1);
int year=atoi(s.Left(4));
int month=atoi(s.Mid(first+1,second-first+1));
int day=atoi(s.Mid(second+1,s.GetLength()-second-1));
CTime temp(year,month,day,0,0,0);
7.判断CString是否表示的正确日期格式
//判断是否为2004-01-13 ch 可代表其他分隔符
bool IsDate(CString str,char ch)
{
if(str.IsEmpty()) return false;
//日期分段
int first=str.Find(ch);
int second=str.Find(ch,first+1);
int year=atoi(str.Left(4));
int month=atoi(str.Mid(first+1,second-first+1));
int day=atoi(str.Mid(second+1,str.GetLength()-second-1));
//判断
if (year < 2000 || year >= 2010)
{
return false;
}
else if (month< 1 || month >12)
{
return false;
}
else if (day< 1 || day > 31)
{
return false;
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
if(day > 30)
{
return false;
}
else
{
return true;
}
}
else if (month == '2')
{
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
{
if (day>29)
{
return false;
}
else
{
return true;
}
}
else if (day>28)
{
return false;
}
return true;
}
else
{
return true;
}
}
四、
在MFC中操作时间的类主要有两对:CTime和CTimeSpan与COleDateTime和COleDateTimeSpan,CTime和CTimeSpan主要封装了ANSI time_t和关于time_t的Run-Time库的主要函数,CTime里面使用的成员变量是time_t类型,该类型是个long型,由于long类型的原因,所以该类只能处理4294967296秒约68年的数据,所以用CTime只能处理1970年到2038年的日期。
幸好,MFC同时提供了COleDateTime和COleDateTimeSpan类,使用该两个类完全可以代替CTime和CTimeSpan,COleDateTime和COleDateTimeSpan类所使用的成员变量是DATE类型,该类型是个double类型,而且使用的单位是日,所以可以处理从100年1月1日到9999年12月31日的日期时间,COleDateTime类的日期计算主要是操作公有成员变量COleDateTime::m_dt,该变量是DATE即double类型,该变量是为零时是1899年12月30日0时0分0秒,大于零时的日期比1899年12月30日0时0分0秒大,反之亦然,例如:
COleDateTime t;
t.m_dt=0;
AfxMessageBox(t.Format("%Y-%m-%d %H:%M:%S"));
运行的结果是:1899-12-30 00:00:00
COleDateTime t;
t.m_dt=39444.437731;
AfxMessageBox(t.Format("%Y-%m-%d %H:%M:%S"));
运行的结果是:2007-10-28 10:30:20
反过来以可以得到变量的值,例如:
COleDateTime t(2004,12,28,22,22,22);
CString str;
str.Format("%f",t.m_dt);
AfxMessageBox(str);
运行的结果是:38349.932199
COleDateTimeSpan类是用于对COleDateTime类的两个时间的时间间隔的计算,COleDateTimeSpan类使用的成员变量COleDateTimeSpan::m_span是一个double类型是用于记录两个COleDateTime::m_dt的时间差,例如:
COleDateTime t1(2006,1,1,0,0,0);
COleDateTime t2(2007,1,1,0,0,0);
COleDateTimeSpan ts=t2-t1;
CString str;
str.Format("%f",ts.m_span);
AfxMessageBox(str);
运行的结果是:365.000000
反过来也可以得到日期
COleDateTime t1(2006,1,1,0,0,0);
COleDateTimeSpan ts;
ts.m_span=400.0;
COleDateTime t2=t1+ts;
AfxMessageBox(t2.Format("%c"));
运行的结果是:02/05/07 00:00:00
可是在使用COleDateTimeSpan类中以下的几个函数可要小心,这不知道是不是MFC的一个Bug,
double GetTotalDays( ) const;
double GetTotalHours( ) const;
double GetTotalMinutes( ) const;
double GetTotalSeconds( ) const;
几个函数的返回值都是double类型
但是,如double GetTotalSeconds( ) const;在MFC内部的原形是:
_AFXDISP_INLINE double COleDateTimeSpan::GetTotalSeconds() const
{ ASSERT(GetStatus() == valid);
long lReturns = (long)(m_span * 24 * 60 * 60 + AFX_OLE_DATETIME_HALFSECOND);
return lReturns;
}
看到没有,它返回的实际是个long类型,并不是一个double类型,所以在使用这几个函数的时候计算两个时间的间隔不要太大,特别是GetTotalSeconds( )函数,如计算两个时间的间隔大于68年时就会溢出,所以我建议直接读取COleDateTimeSpan::m_span变量的值,这是一个单位为日的时间间隔,例如:
COleDateTime t1(2000,1,1,0,0,0);
COleDateTime t2(2070,1,1,0,0,0);
COleDateTimeSpan ts=t2-t1;
CString str;
str.Format("%f",ts.GetTotalSeconds());
AfxMessageBox(str);
运行的结果是:-2085892096.000000
这个结果明显是一个溢出,如果使用
str.Format("%f",ts.m_span*86400);
则会得到2209075200.000000。
所以灵活使用COleDateTime类的m_dt变量和COleDateTimeSpan类的m_span变量操作会得到意想不到的收获
http://blog.csdn.net/andyvccc/article/details/5949098
mfc小工具开发之定时闹钟之---时间获取和音频播放的更多相关文章
- mfc小工具开发之定时闹钟之---功能介绍
使用背景: 之前在xp上用过飞雪日历,感觉挺好用的,还有在音频上的兴趣,促使了我也要自己做一个简单的定时闹钟. 之前开发过图片格式的小工具,没来的急分享,后期整理后,一块奉上,写这篇介绍的时候已近完成 ...
- mfc小工具开发之定时闹钟之---二十四小时时区和时间段
1.凌晨0:00-6:00时显示凌晨,上午6:00-12:00显示上午,中午12:00-14:00显示中午,下午14:00-显示下午,晚上18:00-24:00显示晚上 2. 早上:6-8:上午8-1 ...
- mfc小工具开发之定时闹钟之---多线程急线程同步
一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...
- WordPress小工具开发教程(网站公告)
WordPress小工具开发教程(网站公告) BY TIANQIXIN · 2012 年 12 月 26 日 wordpress主题小工具,可以自由拖动到侧边栏,并在前台实现相应功能!一般自带的小 ...
- 利用ncurses库开发终端工具箱(1)—— ToDoList小工具开发
准备工作 腾讯云服务器(Ubuntu),C++编程语言 由于想输出界面中包含中文,所以安装库 libncursesw5,依次输入下面三行命令 sudo apt-get install libncurs ...
- C# 小工具开发--DeBugHttp
随着RESTful的流行,前后端分离,我们后端开发人员在开发过程中多http相关方法进行测试.这就是这个小工具的初衷. 代码地址:https://github.com/gdoujkzz/DebugHt ...
- Windows 桌面边栏小工具开发入门
准备为网站做一个桌面通知功能的工具,现在网上一般是html5+js的比较多.虽然html5+js现在是web的开发主流,但是我们应用一般是windows系统.并且应使用中,需要打开谷歌或其 ...
- 【原】得心应手小工具开发——IE代理快速切换工具
一.引入 因为公司里上外网要经常换IE代理地址,每次切换地址都要进到Internet Options里去设置一番,经常切换的话很是麻烦,由于用了点时间作个小工具来方便自己. 二.实现思路 其实思路很简 ...
- 语音转文字小工具开发Python
# -*- coding: utf- -*- import requests import re import os import time from aip import AipSpeech fro ...
随机推荐
- 【转】Socket状态变迁图
转自:http://www.cnblogs.com/ILove/archive/2008/12/08/1350430.html 服务端,端口的状态变化 先在本机(IP地址为:192.168.1.1 ...
- 使用VisualSVN建立SVN服务器
原地址:http://blog.csdn.net/happyjiang2009/article/details/5719988 以前使用官方Subversion搭建SVN版本控制环境,感觉很繁琐,需要 ...
- Introducing MVC
PS:这本书感觉不怎么样,这么多低频词就倒人胃口... Suppose you'v recently launched a new web site, only to find that it's s ...
- WindowManager.LayoutParams全解
WindowManager是Android中一个重要的服务(Service ).WindowManager Service 是全局的,是唯一的.它将用户的操作,翻译成为指令,发送给呈现在界面上的各个W ...
- JDBC数据库编程:ResultSet接口
掌握ResultSet接口 使用ResultSet接口进行查询 ResultSet接口 在JDBC操作中,数据库所有查询记录将使用ResultSet进行接收,并使用ResultSet显示内容. 常用方 ...
- docker中批量删除 tag为none的镜像
添加定时任务,批量删除tag 为none 的镜像 ,释放磁盘空间 [root@weifeng]:~# crontab -l */ * * * /usr/bin/docker rmi `docker ...
- input-form-select-a-img-ul-dl标签
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 【转】火星坐标、百度坐标、WGS-84坐标相互转换及墨卡托投影坐标转经纬度JavaScript版
原文地址:https://www.cnblogs.com/fwc1994/p/5884115.html 火星坐标 火星坐标是国家测绘局为了国家安全在原始坐标的基础上进行偏移得到的坐标,基本国内的电子地 ...
- java基础讲解13-----集合
一:集合介绍 import java.util.ArrayList;import java.util.Collection;import java.util.Iterator; public clas ...
- 使用swagger实现在线api文档自动生成 在线测试api接口
使用vs nuget包管理工具搜索Swashbuckle 然后安装便可 注释依赖于vs生成的xml注释文件