利用键盘钩子开发按键发音程序
2010-01-09 20:31:49 来源:WEB开发网有一点必须说明,标准键盘有101个键,您想让多少键发声音,就必须在上面的KeyboardProc动作里定义多少个键,常用的10个数字键和26个英文字 母不会给您带来太大的困难,只要相应的'A'对应A键,'1'对应1键就可以,但如果您希 望能让更多的键都有各种特色音乐的话,很可能会遇到一些键盘编码上的麻烦,比如ESC键就不能简单的 用'ESC'来搞定了,得用VK_ESCAPE,又比如Alt键得用VK_MENU来定义,没有个键盘编码表的话 会令人相当头疼,这里我介绍一种让程序来告诉您键盘按键名称的方法:
为一个工程添加PreTranslateMessage映射,添加如下代码:
char KeyName[50];
ZeroMemory (KeyName,50);
if(pMsg -> message == WM_KEYDOWN)
{
GetKeyNameText(pMsg ->lParam,KeyName,50);
MessageBox(KeyName);
}
那么当程序窗口显示在面前时按下某个键,就会弹出一个消息显示该键的名称,然后用''包起来就可以了,比如逗号 句号,就是','和'.',简单吧:)
到此就全部完成了按键发音程序的编写,通过改变声音文件的名称而不用改动程序本身就可以达到更换按键声音的目的了,只是有个遗憾,声音文件 在硬盘中的位置不能变更,从C盘换移动D盘程序就不能播放了,怎么样才能灵活的读取声音文件呢?可以用API函数GetModuleFileName来得到程序所在的目录,具体实现方法如下:
(1)在Hook.h的 public:下面添加:
BOOL InitInstance(); //初始化函数
(2)在Hook.cpp的 #endif下添加定义全局变量的代码:
char szBuf[256];
char *p;
CString msg;
(3)在Hook.cpp中适当位置添加:
BOOL CHookApp::InitInstance ()
{
hins=AfxGetInstanceHandle();
GetModuleFileName(AfxGetInstanceHandle( ),szBuf,sizeof(szBuf));
p = szBuf;
while(strchr(p,'\\'))
{
p = strchr(p,'\\');
p++;
}
*p = '\0';
msg=szBuf;
return TRUE;
}
(4)新建一个文件夹并命 名为Sound;
(5)改变声音文件物理位置定义方式
case '1':sndPlaySound (msg+"sound\\1.wav",SND_ASYNC);break;
msg是得到程序当前所在目录,加上后面的代码就是指播放当前目录下的Sound目录里的1.wav文件,这样就将声音文件的绝对路径改成了灵活 的相对路径.您只要把KeySound.exe,Hook.dll和Sound文件夹放在同一个文件夹下,以后只要搬动整个文件夹就能实现声音文件的任意移动了。
调试时需要注意:将Hook.dll、Sound目录放在 KeySound.exe的执行目录下。假如编译链接的时候出现unresolved external symbol __imp__sndPlaySoundA@8 这样的信息,请在Project Settings中加入Winmm.lib 。
更多精彩
赞助商链接