#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