下载:
//把工程保存为KeyBoarHook.dpr,并实现如下:以下知识都来自万一老师的博客library KeyBoarHook;{$R 'New1.res' 'New1.rc'}{$R *.dres}uses
SysUtils, Windows, Messages, Classes, DirectSound, MMSystem, ReadWave in 'ReadWave.pas';//这个文件是万一老师编的同时播放多个声音文件的单元,//ReadWave 是上面重新定义的单元; //ReadWave 是上面重新定义的单元
{$R *.res} const KeyPressMask = $80000000;//掩码常量,让按一次只发声一次var //tada: Pointer; dllHandle:THandle; keyboardhook: HHOOK; {钩子变量} myDSound: IDirectSound8; bufs: array[0..5] of IDirectSoundBuffer; //缓冲区数组, 用于装载资源文件中的三个 WAVE 文件{使用资源文件建立缓冲区并播放}
procedure PlayResourceWave(ResName: string; var buf: IDirectSoundBuffer; loop: Boolean=false);var bufDesc: TDSBufferDesc; wav: TReadWave; p1: Pointer; n1: DWORD;begin buf := nil; wav := TReadWave.Create; if not wav.OpenResource(ResName) then begin wav.Free; Exit; end; ZeroMemory(@bufDesc, SizeOf(TDSBufferDesc)); bufDesc.dwSize := SizeOf(TDSBufferDesc); bufDesc.dwFlags := DSBCAPS_STATIC; bufDesc.dwBufferBytes := wav.Size; bufDesc.lpwfxFormat := @wav.Format;myDSound.CreateSoundBuffer(bufDesc, buf, nil);
buf.Lock(0, 0, @p1, @n1, nil, nil, DSBLOCK_ENTIREBUFFER);
wav.Read(p1, n1); buf.Unlock(p1, n1, nil, 0); if loop then buf.Play(0, 0, DSBPLAY_LOOPING) else buf.Play(0, 0, 0); wav.Free;end;//初始化声音设备function Setstart: Boolean; stdcall;begin dllHandle:=GetModuleHandle('KeyBoarHook.dll'); //取得dll自己的句柄 DirectSoundCreate8(nil, myDSound, nil); myDSound.SetCooperativeLevel(dllHandle, DSSCL_NORMAL);//原来这里使用Handle会出错,现在把它改成dll自己的句柄 end; procedure Playsound2;stdcall; varss:string; begin ss:='c:\yp\0.wav'; playsound(pchar(ss),0,SND_ASYNC); PlayResourceWave('wav_1', bufs[0], False);//这里不起作用 end;function Playsound1: Boolean; stdcall;varss:string;begin ss:='c:\yp\0.wav'; playsound(pchar(ss),0,SND_ASYNC); PlayResourceWave('wav_1', bufs[0], False);//这里不起作用 end;function KeyHook(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
varinfo:string;ss:string;jianno:integer;niany:bool;begin if ((lParam and KeyPressMask)= 0) and (wParam = 96) then Playsound(pchar('wav1'),hinstance,SND_ASYNC or snd_resource); Result := CallNextHookEx(keyboardhook, nCode, wParam, lParam);end;{建立钩子}
function SetHook: Boolean; stdcall;constWH_KEYBOARD_LL=13;begin keyboardhook := SetWindowsHookEx(WH_KEYBOARD, @KeyHook, HInstance, 0);//这里WH_KEYBOARD_会出错 Result := keyboardhook <> 0;end;{释放钩子}
function DelHook: Boolean; stdcall;begin Result := UnhookWindowsHookEx(keyboardhook);end;{
释放次缓冲区,不然会内存出错}function Delbufs: Boolean; stdcall;variii:Integer;begin for iii := Low(bufs) to High(bufs) do bufs[iii] := nil; myDSound := nil;end;{按 DLL 的要求输出函数}
exports SetHook ,//name 'SetHook', DelHook ,//name 'DelHook', KeyHook , Setstart, Playsound1, Playsound2,//name 'KeyHook', delbufs;beginend.