你好,游客 登录 注册 搜索
背景:
阅读新闻

鼠标滚轮调节音量 (含程序和源程序下载) - Augusdi的专栏

[日期:2013-04-04] 来源:  作者: [字体: ]

http://hi.baidu.com/qiujiejia/item/df0ee3a03760c813a9cfb760

鼠标滚轮调节音量 (含程序和源程序下载)

自己做的一个用鼠标滚轮调节系统音量的程序(Win32编程),拿出来跟大家分享.
只要把鼠标移到屏幕上方(或下方)滚动鼠标中键就可以调节音量大小


程序: WheelVolume.zip(请不要使用迅雷直接下载)

源程序:WheelVolume_source.zip(在VC6下编译通过) (请不要使用迅雷直接下载)

备注: 以上为xp下的程序和源代码,win7 版本的 请到qq邮箱里下载

 vcshare@ qq.com(密码:share88)

 


源代码:

#define   _WIN32_WINNT   0x0500   
#include <windows.h>
#include <stdio.h>
#include "resource.h"

//调节音量的函数需要winmm.lib
#include <mmsystem.h>
#define _WIN32_WINNT 0x0500
#pragma comment(lib,"winmm.lib")

//当中建滚动时,向窗口发送此消息以使窗口显示当前音量值
#define WM_ADJUSTVOLUME WM_USER+100

//音量分20个值
#define TOTAL_PERCENT 20

//窗口大小 
#define WIDTH 300  
#define HEIGHT 28  

//绘制每一小格的大小
#define EACH_WIDTH (WIDTH-51)/TOTAL_PERCENT 
#define EACH_HEIGHT HEIGHT-4

//最低音量和最高音量分20个值
#define INTERVAL 20  

int MousePos=0;   //标志位
HWND g_hWnd;   //窗口句柄
HHOOK g_hMouse=NULL; //钩子句柄


bool WINAPI SetVolume(LONG vol); //设置音量值
unsigned WINAPI GetVolume();   //获得音量值


//鼠标钩子,捕获中键滚动的消息
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam, LPARAM lParam)

if (nCode<0 )
   return CallNextHookEx(g_hMouse,nCode,wParam,lParam); //传递钩子信息

if (wParam==WM_MOUSEWHEEL)
{
   POINT point=(POINT)((MSLLHOOKSTRUCT *)lParam)->pt;
//鼠标是否在指定的地方滚动中建
   if ( unsigned(point.y-MousePos)<20 )
   {
    int zDelta= (int)(((MSLLHOOKSTRUCT *)lParam)->mouseData );
    (int(zDelta)>0) ? zDelta=-1 : zDelta=1;
   //重新设置音量
    int volume=GetVolume()+zDelta;
   //假如音量超出0-20,则设为0或20 
    if (volume<0) volume=0;
    if (volume>INTERVAL) volume=INTERVAL;
   //设置音量
    SetVolume(volume); 
   //假如窗口隐藏了,显示窗口
    if (!IsWindowVisible(g_hWnd))
    {
     ::SetWindowPos(g_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); //保证窗口在最顶层
     ShowWindow(g_hWnd,SW_SHOWNOACTIVATE);   //显示窗口
    }
   //绘制音量图形  
    PostMessage(g_hWnd,WM_ADJUSTVOLUME,volume,0);
   //避免WM_MOUSEWHEEL向下钩子传递
    return 1;
   }
}
return CallNextHookEx(g_hMouse,nCode,wParam,lParam); //传递钩子信息 
}

//主窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{

//假如已经有一个实例在运行,则显示已经运行的实例
HANDLE m_hMutex = CreateMutex(NULL,FALSE,"efe3ty34twgr4235325efwrwgrdgrg");   //记得在程序末尾调用CloseHandle( m_hMutex )
if (GetLastError()==ERROR_ALREADY_EXISTS)
{
   HWND PreWnd=FindWindow(NULL,"WheelVolume");
   ShowWindow(PreWnd,SW_SHOWNOACTIVATE);
   RECT rect;
   GetWindowRect(PreWnd,&rect);
   SetCursorPos(rect.left+10,rect.top+10);
   PostMessage(PreWnd,WM_RBUTTONDOWN,0,0);
   CloseHandle( m_hMutex );
   return FALSE;
}
//窗口类
WNDCLASS wndclass;
wndclass.lpszClassName="MyClass";    // window class name
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); 
wndclass.lpszMenuName=NULL;
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON));
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=WndProc;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
RegisterClass(&wndclass);

//加载设置
char buf[10]={0};
GetProfileString("WheelVolume","MousePos","0",buf,10);
MousePos=atoi(buf);

//获得显示窗口的X y 坐标
char Xbuf[10]={0};
char Ybuf[10]={0};
GetProfileString("WheelVolume","Postion_X","0",Xbuf,10);
GetProfileString("WheelVolume","Postion_Y","0",Ybuf,10);
int x=atoi(Xbuf);
int y=atoi(Ybuf);
if ( x<0 || y<0 || x>GetSystemMetrics(SM_CXSCREEN) || y>GetSystemMetrics(SM_CYSCREEN) )
{
   x=0;
   y=0;

//创建窗口
g_hWnd= CreateWindowEx( WS_EX_TOOLWINDOW|WS_EX_TOPMOST,"MyClass","WheelVolume",WS_POPUP | WS_CLIPSIBLINGS |WS_BORDER,x,y,WIDTH,HEIGHT,NULL,NULL,hInstance,NULL) ;
//启动鼠标低级钩子
g_hMouse=SetWindowsHookEx(WH_MOUSE_LL,MouseProc,GetModuleHandle(NULL),0);//这里用GetModuleHandle(NULL)来把自身作为一个保存钩子处理函数的dll


//消息循环
MSG msg;
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 int CurrentValue=0;
switch(message)
{
case WM_CREATE:
   {
    //判断是否第一次运行
    char buf[4]={0};
    GetProfileString("WheelVolume","IsFirstExcute","0",buf,4);
    if (!strcmp(buf,"0"))
    {
     WriteProfileString("WheelVolume","IsFirstExcute","1"); //修改参数

     ::MessageBox(hWnd,TEXT("EasyVolume第一次运行"),"提示",MB_OK);
     ShowWindow(hWnd,SW_SHOWNOACTIVATE);
     RECT rect;
     GetWindowRect(hWnd,&rect);
     SetCursorPos(rect.left+10,rect.top+10);
     PostMessage(hWnd,WM_RBUTTONDOWN,0,0); 
    }
   }

case WM_PAINT:
   {
    PAINTSTRUCT ps;
    HDC hdc= BeginPaint(hWnd, &ps);
    {
     //画界面
     HDC hdc=::GetDC(g_hWnd);
     HBRUSH brush=CreateSolidBrush(RGB(200,23,23)); //颜色
     SelectObject (hdc,brush) ;    
     for (int i=0;i<CurrentValue;i++)       //画音量界面
      ::Rectangle(hdc,2+i*EACH_WIDTH,2,(i+1)*EACH_WIDTH,EACH_HEIGHT);    
     DeleteObject(brush);
     ::ReleaseDC(g_hWnd,hdc) ;
    }
    //画百分数
    char buf[10]={0}; 
    sprintf(buf,"%d %%",100/TOTAL_PERCENT*CurrentValue);
    ::SetBkMode(hdc,TRANSPARENT);
    RECT rect={WIDTH-50,0,WIDTH,HEIGHT};
    ::DrawText (hdc,buf, -1,&rect,DT_SINGLELINE | DT_LEFT | DT_VCENTER |DT_END_ELLIPSIS ) ;

    EndPaint(hWnd, &ps);
    SetTimer(g_hWnd,1,1000,NULL);
   }
   break;
case WM_ADJUSTVOLUME:
   {
    CurrentValue=wParam;
    RECT rect={ 2+CurrentValue*EACH_WIDTH,2,WIDTH,EACH_HEIGHT}; //无效区域
    InvalidateRect(g_hWnd,&rect,true);    //更新 
   }
   break;
case WM_TIMER:
   ShowWindow(g_hWnd,SW_HIDE);
   break;
case WM_LBUTTONDOWN:
   {
    KillTimer(hWnd,1);
   //移动窗口
    POINT point;
    point.x= LOWORD (lParam) ;
    point.y= HIWORD (lParam) ;
    SendMessage(hWnd,WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));   //在LBUTTONDOWN里加,可以移动窗口
   //获得当前窗口的大小
    RECT rect;
    GetWindowRect(hWnd,&rect);
   //假如窗口超过窗口边界,调整之
    if (rect.left<0) rect.left=0;
    if (rect.top<0) rect.top=0;
    if (rect.right>GetSystemMetrics(SM_CXSCREEN)) rect.left=GetSystemMetrics(SM_CXSCREEN)-(rect.right-rect.left);
    if (rect.bottom>GetSystemMetrics(SM_CYSCREEN)) rect.top=GetSystemMetrics(SM_CYSCREEN)-(rect.bottom-rect.top);
   //重新设置窗口位置
    SetWindowPos(hWnd,NULL,rect.left,rect.top,0,0,SWP_NOSIZE);
    char buf[10];
   //保存窗口
    WriteProfileString("WheelVolume","Postion_X",itoa(rect.left,buf,10));
    WriteProfileString("WheelVolume","Postion_Y",itoa(rect.top,buf,10));
  
    SetTimer(hWnd,1,1000,0);
   }
   break;
case WM_RBUTTONDOWN:
   {
   //打开菜单时停止自动隐藏功能
    KillTimer(hWnd,1);
   //创建菜单
    HMENU hMenuPopup = CreatePopupMenu () ;
    AppendMenu    (hMenuPopup, MF_STRING, 0, "当鼠标接近屏幕上方时使用滚轮调节音量");
    AppendMenu    (hMenuPopup, MF_STRING, 1, "当鼠标接近屏幕下方时使用滚轮调节音量");
    AppendMenu    (hMenuPopup, MF_STRING, 2, "开机时自动启动");
    AppendMenu    (hMenuPopup, MF_STRING, 3, "退出程序");
    AppendMenu    (hMenuPopup, MF_STRING, 4, "下载源程序");
    AppendMenu    (hMenuPopup, MF_STRING, 5, "说明:左键拖动可改变窗口位置,按右键可弹出设置菜单");

    EnableMenuItem(hMenuPopup,5,MF_BYPOSITION | MF_DISABLED|MF_GRAYED);
   //对应的启动方式(上方 或 下方)选项前打勾
    if(MousePos==0)
     CheckMenuItem(hMenuPopup,0,MF_BYPOSITION | MF_CHECKED);
    else
     CheckMenuItem(hMenuPopup,1,MF_BYPOSITION | MF_CHECKED);
   //假如开机自动启动,着在"开机时自动启动"菜单前打勾标记
    HKEY RegEntry;   
    RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",0, KEY_READ,&RegEntry);   
    char filename[MAX_PATH]={0};
    DWORD WordType=REG_SZ;   
    DWORD WordData=sizeof(filename);   
    long ret=RegQueryValueEx(RegEntry,"VolumeChange",0,&WordType,(LPBYTE)filename,&WordData);
    if   (ret == ERROR_SUCCESS)   
     CheckMenuItem(hMenuPopup,2,MF_BYPOSITION | MF_CHECKED); 
    RegCloseKey(RegEntry);
   //打开右键菜单
    POINT point;
    GetCursorPos(&point);
    TrackPopupMenu (hMenuPopup, TPM_RIGHTBUTTON,point.x,point.y, 0, hWnd, NULL) ;
    DestroyMenu (hMenuPopup);
    SetTimer(hWnd,1,1000,0);
   }
   break;
case   WM_COMMAND:
   switch (LOWORD (wParam)) 
   {
   case 0:   //设置"当鼠标接近屏幕上方时使用滚轮调节音量"
    MousePos=0;
    WriteProfileString("WheelVolume","MousePos","0"); 
    ::SetWindowPos(hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOACTIVATE);
    break;
   case 1:   //设置"当鼠标接近屏幕下方时使用滚轮调节音量"
    char buf[10];
    MousePos=GetSystemMetrics(SM_CYSCREEN)-20; 
    WriteProfileString("WheelVolume","MousePos",itoa(MousePos,buf,10)); //保存设置
    ::SetWindowPos(hWnd,HWND_TOPMOST,0,GetSystemMetrics(SM_CYSCREEN)-HEIGHT,0,0,SWP_NOSIZE|SWP_NOACTIVATE);
    break;
   case 2:   //判断并修改"开机自动启动选项"
    {
     HKEY RegEntry;   
     RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",0, KEY_ALL_ACCESS,&RegEntry);   
     char FilePath[MAX_PATH]={0};
     DWORD WordType=REG_SZ;   
     DWORD WordData=sizeof(FilePath);   
     long ret=RegQueryValueEx(RegEntry,"VolumeChange",0,&WordType,(LPBYTE)FilePath,&WordData);
     if   (ret == ERROR_SUCCESS)   
      RegDeleteValue(RegEntry,"VolumeChange"); 
     else
     {
      GetModuleFileName(NULL, FilePath, sizeof(FilePath));
      RegSetValueEx(RegEntry,"VolumeChange",0,REG_SZ,(LPBYTE)FilePath,sizeof(FilePath))   ; 
     }
     RegCloseKey(RegEntry);
    }
    break;
   case 3:   //推出程序
    UnhookWindowsHookEx(g_hMouse) ;
    PostQuitMessage(0);
    break;
   case 4:
    ShellExecute(hWnd, "open", "http://sites.google.com/site/qiujiejia1/Home/WheelVolume_source.zip", NULL, NULL, SW_SHOWNORMAL); 
   }
   break;
default:
   return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}


bool GetVolumeControl(HMIXER hmixer ,long componentType,long ctrlType,MIXERCONTROL* mxc)
{
   MIXERLINECONTROLS mxlc;
   MIXERLINE mxl;
   mxl.cbStruct = sizeof(mxl);
   mxl.dwComponentType = componentType;
   if(!mixerGetLineInfo((HMIXEROBJ)hmixer, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE))
   {
      mxlc.cbStruct = sizeof(mxlc);
      mxlc.dwLineID = mxl.dwLineID;
      mxlc.dwControlType = ctrlType;
      mxlc.cControls = 1;
      mxlc.cbmxctrl = sizeof(MIXERCONTROL);
      mxlc.pamxctrl = mxc;
      if(mixerGetLineControls((HMIXEROBJ)hmixer,&mxlc,MIXER_GETLINECONTROLSF_ONEBYTYPE))
         return 0;
      else
         return 1;
   }
   return 0;
}


unsigned GetVolumeValue(HMIXER hmixer ,MIXERCONTROL *mxc)
{
   MIXERCONTROLDETAILS mxcd;
   MIXERCONTROLDETAILS_UNSIGNED vol; vol.dwValue=0;
   mxcd.hwndOwner = 0;
   mxcd.cbStruct = sizeof(mxcd);
   mxcd.dwControlID = mxc->dwControlID;
   mxcd.cbDetails = sizeof(vol);
   mxcd.paDetails = &vol;
   mxcd.cChannels = 1;
   if(mixerGetControlDetails((HMIXEROBJ)hmixer, &mxcd, MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE))
      return -1;
   return vol.dwValue;
}


bool SetVolumeValue(HMIXER hmixer ,MIXERCONTROL *mxc, long volume)
{
   MIXERCONTROLDETAILS mxcd;
   MIXERCONTROLDETAILS_UNSIGNED vol;vol.dwValue = volume;
   mxcd.hwndOwner = 0;
   mxcd.dwControlID = mxc->dwControlID;
   mxcd.cbStruct = sizeof(mxcd);
   mxcd.cbDetails = sizeof(vol);
   mxcd.paDetails = &vol;
   mxcd.cChannels = 1;
   if(mixerSetControlDetails((HMIXEROBJ)hmixer, &mxcd, MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE))
      return 0;
   return 1;
}


//设置音量值
bool WINAPI SetVolume(LONG vol)
{
bool Result=false;   //用于判断函数是否执行成功
MIXERCONTROL volCtrl;
HMIXER hmixer;
if(mixerOpen(&hmixer, 0, 0, 0, 0)) return 0;
if(GetVolumeControl(hmixer,MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,MIXERCONTROL_CONTROLTYPE_VOLUME,&volCtrl))

   int ChangeValue=volCtrl.Bounds.lMaximum/INTERVAL;
   int TotalValue=ChangeValue*vol;
   if(SetVolumeValue(hmixer,&volCtrl,TotalValue))
    Result=true;
}   
mixerClose(hmixer);
return Result;
}

//返回音量值
unsigned WINAPI GetVolume()
{
unsigned rt=0; 
MIXERCONTROL volCtrl;
HMIXER hmixer; 
if(mixerOpen(&hmixer, 0, 0, 0, 0)) return 0;
if(!GetVolumeControl(hmixer,MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,MIXERCONTROL_CONTROLTYPE_VOLUME,&volCtrl))
   return 0;
int ChangeValue=volCtrl.Bounds.lMaximum/INTERVAL; //每一次调用函数改变的音量值
rt=GetVolumeValue(hmixer,&volCtrl)/ChangeValue;   //GetVolumeValue得到的是具体值
mixerClose(hmixer);
return rt;
}

`

`

大方广 http://www.dfg.cn/gb/学习圣贤之道

《幸福人生讲座》http://www.dfg.cn/gb/djjsh/pxcj/cailaoshi/20041120hk.htm






收藏 推荐 打印 | 录入:admin | 阅读:
相关新闻