1.这里的音频文件是指*.wav格式的音频,参考了飞雪的音频文件,版本号:

飞雪桌面日历 v2.84.1025 绿色版

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小工具开发之定时闹钟之---时间获取和音频播放的更多相关文章

  1. mfc小工具开发之定时闹钟之---功能介绍

    使用背景: 之前在xp上用过飞雪日历,感觉挺好用的,还有在音频上的兴趣,促使了我也要自己做一个简单的定时闹钟. 之前开发过图片格式的小工具,没来的急分享,后期整理后,一块奉上,写这篇介绍的时候已近完成 ...

  2. 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 ...

  3. mfc小工具开发之定时闹钟之---多线程急线程同步

    一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...

  4. WordPress小工具开发教程(网站公告)

    WordPress小工具开发教程(网站公告) BY TIANQIXIN · 2012 年 12 月 26 日   wordpress主题小工具,可以自由拖动到侧边栏,并在前台实现相应功能!一般自带的小 ...

  5. 利用ncurses库开发终端工具箱(1)—— ToDoList小工具开发

    准备工作 腾讯云服务器(Ubuntu),C++编程语言 由于想输出界面中包含中文,所以安装库 libncursesw5,依次输入下面三行命令 sudo apt-get install libncurs ...

  6. C# 小工具开发--DeBugHttp

    随着RESTful的流行,前后端分离,我们后端开发人员在开发过程中多http相关方法进行测试.这就是这个小工具的初衷. 代码地址:https://github.com/gdoujkzz/DebugHt ...

  7. Windows 桌面边栏小工具开发入门

          准备为网站做一个桌面通知功能的工具,现在网上一般是html5+js的比较多.虽然html5+js现在是web的开发主流,但是我们应用一般是windows系统.并且应使用中,需要打开谷歌或其 ...

  8. 【原】得心应手小工具开发——IE代理快速切换工具

    一.引入 因为公司里上外网要经常换IE代理地址,每次切换地址都要进到Internet Options里去设置一番,经常切换的话很是麻烦,由于用了点时间作个小工具来方便自己. 二.实现思路 其实思路很简 ...

  9. 语音转文字小工具开发Python

    # -*- coding: utf- -*- import requests import re import os import time from aip import AipSpeech fro ...

随机推荐

  1. Discuz常见小问题2-如何在新建的页面上只显示一部分板块

    切换到论坛-版块管理,记住要只显示的板块的gid(比如我的是36)   为某个主导航设置一个单独的php页面(名字自己取)   如果这个页面内容跟首页forum.php完全一样,只是第三行增加了一句话 ...

  2. RTSP - RTP over TCP

    RTP over RTSP(TCP)(一)   RTP over RTSP包混合发送的解决办法   RTSP - RTP over TCP     To use TCP communication, ...

  3. 网络编程入坑基础-BIO总结

    IO总结 前提 参考资料: <Java I/O> -- 这本书没有翻译版,需要自己啃一下. <Java I/O>这本书主要介绍了IO和NIO的相关API使用,但是NIO部分并不 ...

  4. 修改tcp数据内容

    http://blog.sina.com.cn/s/blog_6f0c85fb0100xi1x.html 2.6内核基于NetFilter处理框架修改TCP数据包实现访问控制 参考上面的钩子函数,结合 ...

  5. Odoo/OpenERP 日志配置、使用及实现

    当应用处于生产环境时,日志提供了有价值的运行时调试及监控信息,并且,也是一个有用的调试工具对于处于开发阶段的应用来说.此文描述在Odoo8.0中日志的配置.使用及实现 日志配置        Odoo ...

  6. Errors occurred during the build

    Errors occurred during the build.Errors running builder 'Integrated External Tool Builder' on projec ...

  7. 详细解说 STL 排序(Sort)(转)

    作者Winter 详细解说 STL 排序(Sort) 0 前言: STL,为什么你必须掌握 1 STL提供的Sort 算法 1.1 所有sort算法介绍 1.2 sort 中的比较函数 1.3 sor ...

  8. 对正在运行的mysql进行监控

    对正在运行的mysql进行监控,其中一个方式就是查看mysql运行状态. (1)QPS(每秒Query量) QPS = Questions(or Queries) / seconds mysql &g ...

  9. HTML-HTML5+CSS3权威指南阅读(五、设备像素和CSS像素的概念)

    在这个迷你系列的文章里边我将会解释viewport,以及许多重要元素的宽度是如何工作的,比如<html>元素,也包括窗口和屏幕 这篇文章是关于桌面浏览器的,其唯一目的就是为移动浏览器中相似 ...

  10. excel导入sql server 文本被截断,或者一个或多个字符在目标代码页中没有匹配项 错误处理

    excel导入sql server 文本被截断,或者一个或多个字符在目标代码页中没有匹配项 错误处理方法: 方案1:修改注册表 出现文本被截断的原因是SQL Server的导入导出为了确定数据表的字段 ...