一个控制声音的程序(代码如下:)

类别:编程语言 点击:0 评论:0 推荐:

#include <windows.h>
#include <stdio.h>
#include "release\resource.h"

#define WM_SETSOUND     WM_USER+1
#define WM_MY_TRAY_NOTIFICATION     WM_USER+2
#define WM_CHOOSEWAY    WM_USER+3

#pragma comment(lib,"winmm.lib")

//回调函数声明
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

//全局函数声明
//BOOL TrayMessage(HWND,DWORD,HICON,PSTR);
BOOL TrayMessage(HWND hWnd, DWORD dwMessage, HICON hIcon, PSTR pszTip)
{
 BOOL res;

    NOTIFYICONDATA tnd;

    tnd.cbSize  = sizeof(NOTIFYICONDATA);
    tnd.hWnd  = hWnd;
    tnd.uID   = ID_TRAYICON;
 tnd.uFlags  = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    tnd.uCallbackMessage= WM_MY_TRAY_NOTIFICATION;
    tnd.hIcon  = hIcon;
    lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));

    res = Shell_NotifyIcon(dwMessage, &tnd);
 return res;
}

//主函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
       LPSTR lpcmdLine,int nCmdShow)
{
 
 static TCHAR szAppName[]=TEXT("volume ctrl");
 static TCHAR szClassName[]=TEXT("volume ctrl");
 HWND hwnd;
 MSG msg;
 WNDCLASS wndclass;
 
 wndclass.style=CS_HREDRAW | CS_VREDRAW;
 wndclass.lpfnWndProc=WndProc;
 wndclass.cbClsExtra=0;
 wndclass.cbWndExtra=0;
 wndclass.hInstance=hInstance;
 wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
 wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 wndclass.lpszMenuName=NULL;
 wndclass.lpszClassName=szClassName;
 
 if(!RegisterClass(&wndclass))
 {
  MessageBox(NULL,"Register WNDCLASS FAILTURE!",szAppName,MB_ICONERROR);
  return FALSE;
 }
 
 hwnd=CreateWindow(szClassName,"VOLUME CTRL",
  WS_OVERLAPPEDWINDOW ,CW_USEDEFAULT,CW_USEDEFAULT,
  CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
 
 //下两句取消可使窗口最开始时就不可见
 //ShowWindow(hwnd,nCmdShow);
 //UpdateWindow(hwnd);
 
 while(GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 
 return msg.wParam;
}


//回调函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 //变量声明
 static HINSTANCE hInstance;
    static HMIXER hMixer;       //混频器句柄
 static HMIXER hMixerWave;   //WAVEOUT句柄
    static DWORD m_controlnum;  //用于保存声道数
 static DWORD m_controlid;   //声道的ID
 static LONG m_min;  //声音最小值
 static LONG m_max;   //声音最大值
 static LONG vr,vl;       //左右声道
 static HICON hIcon;
 static HKEY hKey;
 static bChMenu=FALSE,bWave=FALSE,bNoVoilce=FALSE;
 static iChCtrl=0;
 LPTSTR lpBuffer=NULL;
 DWORD dwRegAttr;

 char test[20];

 switch(message)
 {
 case WM_CREATE:
  hInstance=(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE); 
  //注册热键
  RegisterHotKey(hwnd,0xC010,MOD_SHIFT,VK_ADD);
  RegisterHotKey(hwnd,0xC011,MOD_SHIFT,VK_SUBTRACT);
  RegisterHotKey(hwnd,0xC012,MOD_CONTROL,VK_ADD);
  RegisterHotKey(hwnd,0xC013,MOD_CONTROL,VK_SUBTRACT);
  RegisterHotKey(hwnd,0xC014,MOD_CONTROL,VK_MULTIPLY);
  //托盘图标产生
  hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(ID_TRAYICON));
  if(!TrayMessage(hwnd,NIM_ADD,hIcon, "声音控制"))
  {
   return FALSE;
  }
   
  //初始化声音控制
  MIXERCAPS mxcaps;    //混频器容量
  ZeroMemory(&mxcaps, sizeof(MIXERCAPS));
  if (mixerGetNumDevs() != 0)
  {
   if (mixerOpen(&hMixer,0,(DWORD)hwnd,NULL,MIXER_OBJECTF_MIXER | CALLBACK_WINDOW)!= MMSYSERR_NOERROR)
    return FALSE;
   //The mixerGetDevCaps function queries a specified mixer device to determine its capabilities
   if (mixerGetDevCaps((UINT)hMixer, &mxcaps, sizeof(MIXERCAPS))!= MMSYSERR_NOERROR)
    return FALSE;
  }
  if (hMixer == NULL) 
   return FALSE;
  SendMessage(hwnd,WM_SYSCOMMAND,SC_MINIMIZE,0);
  ShowWindow(hwnd,SW_HIDE);
  break;

 case WM_CHOOSEWAY:  //选择控制方式
  MIXERLINE mxl;       //混频器线路数
  mxl.cbStruct = sizeof(MIXERLINE);//必须初始化
  mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
  if (mixerGetLineInfo((HMIXEROBJ)hMixer,
     &mxl,MIXER_OBJECTF_HMIXER |
        MIXER_GETLINEINFOF_COMPONENTTYPE)!= MMSYSERR_NOERROR)  
     return FALSE;

  //MessageBox(hwnd,"OK","",MB_OK);

  if(bWave)
  {
   //MessageBox(hwnd,"OK","",MB_OK);

   DWORD num=mxl.cConnections;
   DWORD type=mxl.dwDestination;

   for( DWORD i=0;i<num;i++)
   {
    mxl.cbStruct      = sizeof(MIXERLINE);
    mxl.dwDestination = type;
    mxl.dwSource      = i;
    if(mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE|MIXER_OBJECTF_HMIXER)!= MMSYSERR_NOERROR)
    {
     MessageBox(hwnd,"GetLinInfo Resource faile!","Error",MB_OK);
     continue;
    }
    if(mxl.dwComponentType==MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT)
     break;
    MessageBox(hwnd,"OK","",MB_OK);
    if(i==num)
    {
     MessageBox(hwnd,"GetLinInfo Resource faile!","Error",MB_OK);
     return FALSE;
    }
   }
  }
  m_controlnum=mxl.cChannels; //声道数量

  MIXERCONTROL mxc;
  MIXERLINECONTROLS mxlc;
  mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
  mxlc.dwLineID = mxl.dwLineID;
  mxlc.dwControlType =MIXERCONTROL_CONTROLTYPE_VOLUME;
  mxlc.cControls =1;
  mxlc.cbmxctrl = sizeof(MIXERCONTROL);
  mxlc.pamxctrl = &mxc;
  if (mixerGetLineControls((HMIXEROBJ)hMixer,
     &mxlc,MIXER_OBJECTF_HMIXER |
     MIXER_GETLINECONTROLSF_ONEBYTYPE )!= MMSYSERR_NOERROR)
     return FALSE;
  //m_name=mxc.szName;
  m_controlid = mxc.dwControlID;
     m_min=mxc.Bounds.lMinimum;
  m_max= mxc.Bounds.lMaximum;
  //sprintf(test,"%d,%d",m_max,m_min);
  //MessageBox(hwnd,test,"",MB_OK);
  
  MIXERCONTROLDETAILS_SIGNED mxcdVolume[2];
  MIXERCONTROLDETAILS mxcd;
  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  mxcd.dwControlID = m_controlid;
  mxcd.cChannels = m_controlnum;
  mxcd.cMultipleItems = 0;
  mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_SIGNED);
  mxcd.paDetails = mxcdVolume;
  if (mixerGetControlDetails((HMIXEROBJ)hMixer,
   &mxcd,MIXER_OBJECTF_HMIXER |
   MIXER_GETCONTROLDETAILSF_VALUE)!= MMSYSERR_NOERROR)          
   return FALSE;
  vl=mxcdVolume[0].lValue;  
  if(m_controlnum==2)  
  {
   vr=mxcdVolume[1].lValue;
  }
  switch(iChCtrl)
  {
  case 1:
   vl+=3000;  //用于声音增大
   vr+=3000;
   if(vl>=m_max||vr>=m_max)
   {
    vl=m_max;
    vr=m_max;
   }
   break;
  case 2:
   vl+=3000;  //用于声音增大
   vr+=3000;
   if(vl>=m_max||vr>=m_max)
   {
    vl=m_max;
    vr=m_max;
   }
   break;
  case 3:
   vl-=3000; ////用于声音减小
   vr-=3000;
   if(vl<=m_min||vr<=m_min)
   {
    vl=m_min;
    vr=m_min;
   }
   break;
  case 4:
   vl-=3000; ////用于声音减小
   vr-=3000;
   if(vl<=m_min||vr<=m_min)
   {
    vl=m_min;
    vr=m_min;
   }
   break;
  }
  SendMessage(hwnd,WM_SETSOUND,0,0);
  break;

 case WM_HOTKEY:
  //MessageBox(hwnd,"key down","",MB_OK);
  //ShowWindow(hwnd,SW_SHOW);
  switch(HIWORD(lParam))   //高字节代表虚拟键
  {
  case VK_ADD: //增加声音热键
   switch(LOWORD(lParam)) //低字节代表控制键
   {
   case MOD_SHIFT:
    //MessageBox(hwnd,"key down","",MB_OK);
    iChCtrl=1;
    bWave=FALSE;
    SendMessage(hwnd,WM_CHOOSEWAY,0,0);
    //sprintf(test,"%d",vl);
    //MessageBox(hwnd,test,"",MB_OK);
    break;

   case MOD_CONTROL:
    //MessageBox(hwnd,"key down","",MB_OK);
    iChCtrl=2;
    bWave=TRUE;
    SendMessage(hwnd,WM_CHOOSEWAY,0,0);
    break;

   default:
    break;
   }
   break;

  case VK_SUBTRACT: //降低声音热键
   switch(LOWORD(lParam))
   {
   case MOD_SHIFT:
    //MessageBox(hwnd,"key down","",MB_OK);
    iChCtrl=3;
    bWave=FALSE;
    //sprintf(test,"%d",vr);
    //MessageBox(hwnd,test,"",MB_OK);
    SendMessage(hwnd,WM_CHOOSEWAY,0,0);
    break;

   case MOD_CONTROL:
    //MessageBox(hwnd,"key down","",MB_OK);
    iChCtrl=4;
    bWave=TRUE;
    SendMessage(hwnd,WM_CHOOSEWAY,0,0);
    break;

   default:
    break;
   }
   break;

   case VK_MULTIPLY: // 设置静音
    /*MIXERLINE mxl;       //混频器线路数
    mxl.cbStruct = sizeof(MIXERLINE);//必须初始化
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
    if (mixerGetLineInfo((HMIXEROBJ)hMixer,
     &mxl,MIXER_OBJECTF_HMIXER |
     MIXER_GETLINEINFOF_COMPONENTTYPE)!= MMSYSERR_NOERROR)  
     return FALSE;
    MIXERCONTROL mxc;
    MIXERLINECONTROLS mxlc;
    mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
    mxlc.dwLineID = mxl.dwLineID;
    mxlc.dwControlType =MIXERCONTROL_CONTROLTYPE_VOLUME;
    mxlc.cControls =1;
    mxlc.cbmxctrl = sizeof(MIXERCONTROL);
    mxlc.pamxctrl = &mxc;
    if (mixerGetLineControls((HMIXEROBJ)hMixer,
     &mxlc,MIXER_OBJECTF_HMIXER |
     MIXER_GETLINECONTROLSF_ONEBYTYPE )!= MMSYSERR_NOERROR)
     return FALSE;
    MIXERCONTROLDETAILS_SIGNED mxcdVolume[2];
    MIXERCONTROLDETAILS mxcd;
    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = m_controlid;
    mxcd.cChannels = m_controlnum;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_SIGNED);
    mxcd.paDetails = mxcdVolume;
    if (mixerGetControlDetails((HMIXEROBJ)hMixer,
     &mxcd,MIXER_OBJECTF_HMIXER |
     MIXER_GETCONTROLDETAILSF_VALUE)!= MMSYSERR_NOERROR)          
     return FALSE;
    vl=mxcdVolume[0].lValue;  
    if(m_controlnum==2)  
    {
     vr=mxcdVolume[1].lValue;
    }
  
    if(hMixer==NULL)
     return FALSE;
    MIXERCONTROLDETAILS_BOOLEAN mxcdMute;
    MIXERCONTROLDETAILS mxcd;
    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = m_controlid;
    mxcd.cChannels = 1;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
    mxcd.paDetails =&mxcdMute;
    if (::mixerGetControlDetails((HMIXEROBJ)hMixer,
     &mxcd,
     MIXER_OBJECTF_HMIXER |
     MIXER_GETCONTROLDETAILSF_VALUE)
     != MMSYSERR_NOERROR)  
     return FALSE;
       mxcdMute.fValue=!mxcdMute.fValue;
    if (::mixerSetControlDetails((HMIXEROBJ)hMixer,
         &mxcd,
         MIXER_OBJECTF_HMIXER |
         MIXER_SETCONTROLDETAILSF_VALUE)
     != MMSYSERR_NOERROR)
     return FALSE;
    break;
  }*/
    bNoVoilce=!bNoVoilce;
  break;

   case WM_COMMAND:
   switch(LOWORD(wParam))
   {
   case ID_START:
    //写入注册表项
    lpBuffer=new char[512]; 
    memset(lpBuffer,0,512);
    GetCurrentDirectory(MAX_PATH,lpBuffer);
    strcat(lpBuffer,"\\volumeCtrl.exe"); 
    RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
     0,NULL,REG_OPTION_NON_VOLATILE,
     KEY_ALL_ACCESS,NULL,&hKey,&dwRegAttr);
    RegSetValueEx(hKey,"volumectrl",0,REG_SZ,(CONST BYTE*)lpBuffer,(DWORD)strlen(lpBuffer)+1);
    RegCloseKey(hKey);
    delete []lpBuffer;
    lpBuffer=NULL;
    bChMenu=TRUE;
    break;

   case ID_UNSTART:
    //删除注册表项
    RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
     0,NULL,REG_OPTION_NON_VOLATILE,
     KEY_ALL_ACCESS,NULL,&hKey,&dwRegAttr);
    RegDeleteValue(hKey,"volumectrl");
    RegCloseKey(hKey);
    bChMenu=FALSE;
    break;

   case ID_EXIT:
    //程序退出时关闭音频设备句柄
    mixerClose(hMixer);
    hMixer = NULL;
    TrayMessage(hwnd,NIM_DELETE,hIcon, "");
    UnregisterHotKey(hwnd,0xC010);
    UnregisterHotKey(hwnd,0xC011);
    UnregisterHotKey(hwnd,0xC012);
    UnregisterHotKey(hwnd,0xC013);
    UnregisterHotKey(hwnd,0xC014);
    PostQuitMessage(0);
    break;
   }
   break;

 case WM_MY_TRAY_NOTIFICATION:
  switch (lParam)
  {
  case WM_RBUTTONDOWN:
   //此处显示右键菜单
   HMENU hMainMenu,hmenuTrackPopup;  //菜单句柄
   POINT pt;

   if(bChMenu==FALSE)
   {
    hMainMenu=LoadMenu(hInstance,MAKEINTRESOURCE(IDM_MAINMENU));
    hmenuTrackPopup = GetSubMenu(hMainMenu, 0);
    ClientToScreen(hwnd,(LPPOINT)&pt);
    if(!GetCursorPos(&pt))
     return FALSE;
    if(!TrackPopupMenu(hmenuTrackPopup,TPM_LEFTALIGN ,pt.x,pt.y,0,hwnd,NULL))
     return FALSE;
   }
   else
   {
    hMainMenu=LoadMenu(hInstance,MAKEINTRESOURCE(IDR_BACKUPMENU));
    hmenuTrackPopup = GetSubMenu(hMainMenu, 0);
    ClientToScreen(hwnd,(LPPOINT)&pt);
    if(!GetCursorPos(&pt))
     return FALSE;
    if(!TrackPopupMenu(hmenuTrackPopup,TPM_LEFTALIGN ,pt.x,pt.y,0,hwnd,NULL))
     return FALSE;
   }
   break;
  }
  break;

 case WM_SETSOUND:
  //sprintf(test,"%d",vr);
  //MessageBox(hwnd,test,"",MB_OK);
  if(bNoVoilce)
  {
   SendMessage(hwnd,WM_CHOOSEWAY,0,0);
   mxcdVolume[0].lValue=m_min;
   if(m_controlnum==2)  
   {
    mxcdVolume[1].lValue=m_min;
   }
  }
  else
  {
   mxcdVolume[0].lValue=vl;
   if(m_controlnum==2)  
   {
    mxcdVolume[1].lValue=vr;
   }
  }
  mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
  mxcd.dwControlID = m_controlid;
  mxcd.cChannels = m_controlnum;
  mxcd.cMultipleItems = 0;
  mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_SIGNED);
  mxcd.paDetails = mxcdVolume;
  if (mixerSetControlDetails((HMIXEROBJ)hMixer,
    &mxcd,MIXER_OBJECTF_HMIXER |
    MIXER_SETCONTROLDETAILSF_VALUE)!= MMSYSERR_NOERROR)
    return FALSE;
  break;   
 }
  return DefWindowProc(hwnd,message,wParam,lParam);
}      

本文地址:http://com.8s8s.com/it/it21797.htm