问题
I am trying to program a "cough button" in a communications program that does not always have focus. I have the code working to mute and unmute the mic (MMDevApi) and it works perfect. I set up a global hot key and this works perfect to set the mute. Now the problem. How do I tell when the Hotkey is released ? I tried a timer as shown in the code but it has an odd behavior. I Hold down my hotkey and the mic mutes immediately then after the interval of the timer it unmutes for a what appears to be half the interval of the timer and then it mutes and stays muted. Without the timer it mutes and stays muted perfectly. I really don't want ( or think it would be any good ) to have to hit a second key to unmute the mic.
//here is my register hot key code !
CoughKeyWnd := AllocateHwnd(CoughKeyWndProc);
CoughKey := GlobalAddAtom('CoughKey');
if CoughKey <> 0 then
RegisterHotKey(CoughKeyWnd, CoughKey, MOD_CONTROL, VK_OEM_3);
//the procedure
procedure TForm1.CoughKeyWndProc(var Message: TMessage);
begin
if Message.Msg = WM_HOTKEY then
begin // to prevent recalling mute
if CoughOn = FALSE then
begin
CoughOn := True;
CoughOff.SetMute(1,@GUID_NULL);
end;
Timer1.Enabled := FALSE;
Timer1.Enabled := True;
end
else
begin
Message.Result := DefWindowProc(CoughKeyWnd, Message.Msg, Message.WParam, Message.LParam);
end;
//and finally the ontimer !
procedure TForm1.JvTimer1Timer(Sender: TObject);
begin
CoughOff.SetMute(0,@GUID_NULL);
Timer1.Enabled := False;
CoughOn := False;
end;
回答1:
You'll see that kind of behavior if your timer expires before the second WM_HOTKEY is retrieved but does not expire retrieving consecutive messages. The time frame between the first and second message is greater than the time frame between consecutive messages. This is because keyboard delay is greater (~250ms typical) than keyboard repeat interval.
To make your approach work, increase your timer interval, something like twice the keyboard delay for instance. You can use SystemParametersInfo to get an approximation for keyboard delay. Or employ a minimum time frame for the microphone to stay in muted state, and only after then start watching for repeated hotkey messages to re-enable your timer. Still, this method will be somewhat unreliable, hotkey messages might be delayed for whatever reason. Better use GetKeyState in your timer handler to test if the keys are still down.
You can install a keyboard hook or register for raw input when the hotkey is hit if you don't want to use the timer.
来源:https://stackoverflow.com/questions/20149761/delphi-xe3-wm-hotkey-how-to-tell-when-hotkey-is-released