2013-11-22 25 views
2

我正在嘗試在通訊程序中編程「咳嗽按鈕」,該程序並不總是有焦點。我有代碼工作來靜音和取消靜音麥克風(MMDevApi),它的工作原理非常完美。我設置了一個全球熱鍵,這對於設置靜音是完美的。現在的問題。如何知道Hotkey何時發佈?我嘗試了代碼中顯示的計時器,但它有一個奇怪的行爲。我在定時器的間隔後立即按住熱鍵和麥克風靜音,取消靜音,看起來是定時器間隔的一半,然後靜音並保持靜音。沒有計時器,它會靜音並保持完美靜音。我真的不想(或認爲這是好事)不得不打開第二把麥克風取消靜音。Delphi XE3 WM_HOTKEY如何判斷何時發佈HotKey?

//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; 
+0

你不明白這些信息。 –

+2

我不認爲這是可能的。 'WM_HOTKEY'通知在發送時發送,但不發送。我將添加一個'[winapi]'標籤來擴大你的Q的觀衆羣,以確認我的想法。 –

+0

我在努力理解爲什麼你需要檢測關鍵。爲什麼你不能只回應熱鍵? –

回答

3

你會看到這種行爲,如果你的計時器到期的第二WM_HOTKEY被檢索過,但沒有到期獲取連續的消息。第一條和第二條消息之間的時間範圍大於連續消息之間的時間範圍。這是因爲鍵盤延遲比鍵盤重複間隔更長(〜250ms典型值)。

爲了使您的方法奏效,請增加計時器間隔,例如鍵盤延遲的兩倍。您可以使用SystemParametersInfo來獲得鍵盤延遲的近似值。或者使用麥克風的最小時​​間段保持靜音狀態,並且只有在開始觀看重複的熱鍵消息才能重新啓用定時器之後。儘管如此,這種方法會有些不可靠,熱鍵消息可能因任何原因而延遲。在計時器處理程序中更好地使用GetKeyState以測試密鑰是否仍然關閉。

如果您不想使用定時器,當熱鍵被擊中時,您可以安裝鍵盤掛鉤或註冊原始輸入。

+0

絕對使用鍵盤掛鉤或註冊原始輸入,而不是使用熱鍵。他們會給你兩個關鍵和關閉的通知。 –