需要取消钩住的按键 [英] Need to cancel a hooked keypress

查看:109
本文介绍了需要取消钩住的按键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨.

我创建了一个音量控制程序,该程序隐藏在后台并响应组合键的"Ctrl +向上箭头"和"Ctrl +向下箭头".除我无法取消向上和向下按键(确实使某些程序混乱)之外,这非常有效.有什么想法吗?

这是我的源代码:

Hi.

I''ve created a volume control program that hides in the background and responds to the key-combo''s "Ctrl + Up Arrow" and "Ctrl + Down Arrow". This is working great except I can''t cancel the up and down keypresses (really messes with certain programs). Any ideas?

Here''s my source code:

Imports System
Imports System.Windows.Forms
Imports System.Runtime.InteropServices

Public Class Form1

    Private Const APPCOMMAND_VOLUME_MUTE As Integer = &H80000
    Private Const APPCOMMAND_VOLUME_UP As Integer = &HA0000
    Private Const APPCOMMAND_VOLUME_DOWN As Integer = &H90000
    Private Const WM_APPCOMMAND As Integer = &H319

    <DllImport("user32.dll")> Public Shared Function SendMessageW(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

    End Function

    'I'm leaving the Mute Sub in for future reference
    Private Sub Mute()
        SendMessageW(Me.Handle, WM_APPCOMMAND, Me.Handle, New IntPtr(APPCOMMAND_VOLUME_MUTE))
    End Sub

    Private Sub DecVol()
        SendMessageW(Me.Handle, WM_APPCOMMAND, Me.Handle, New IntPtr(APPCOMMAND_VOLUME_DOWN))
    End Sub

    Private Sub IncVol()
        SendMessageW(Me.Handle, WM_APPCOMMAND, Me.Handle, New IntPtr(APPCOMMAND_VOLUME_UP))
    End Sub

    Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
    Dim WithEvents Tmr As New Timer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Tmr.Interval = 100
        Tmr.Start()
    End Sub
    Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
        Tmr.Stop()
        If CBool(GetAsyncKeyState(Keys.ControlKey)) And CBool(GetAsyncKeyState(Keys.Up)) Then
            IncVol()
        ElseIf CBool(GetAsyncKeyState(Keys.ControlKey)) And CBool(GetAsyncKeyState(Keys.Down)) Then

            DecVol()
        End If
        Tmr.Start()
    End Sub

    Private Sub ShowHide() Handles Me.Shown
        Me.Hide()
    End Sub

End Class

推荐答案

据我所知,键上/下事件(非字符)无法取消.更确切地说,通过处理KeyDownKeyUp不能取消键/按下事件,但是可以通过处理KeyPressed来取消键按下.

确实不需要P/Invoke函数GetAsyncKeyState.相反,您可以处理上述事件,并在处理程序中检查Shift,Alt或Control键状态.我不确定音量消息,但我认为您无需P/Invoked SendMessage就可以控制音量.

您可以直接使用多媒体模块"winmm.dll",请参见:
http://www.dreamincode.net/forums/topic/45693 -controlling-sound-volume-in-c%23/ [ http://www.geekpedia.com/tutorial176_Get-and-set-the- wave-sound-volume.html [ ^ ].

另请参阅本文: http://www.codeguru.com/csharp/csharp/cs_graphics /sound/article.php/c10931 [ ^ ].

以上方法仍然需要使用P/Invoke.这不是很好.

您可以使用现成的Microsoft .NET类Microsoft.DirectX.AudioVideoPlayback在纯托管代码中工作.请参阅:
http://msdn.microsoft.com/zh-我们/library/windows/desktop/bb324235%28v=vs.85%29.aspx [
To best of my knowledge, key up/down events (non-characters) cannot be cancelled. More exactly, none of key/down events can be cancelled by handling KeyDown or KeyUp, but key press can be cancelled by handling KeyPressed.

The P/Invoke function GetAsyncKeyState is not really needed. Instead, you can handle the above event and check Shift, Alt, or Control key status in the handler. I''m not sure about sound volume messages, but I think you can control sound volume without P/Invoked SendMessage.

You can use multimedia module "winmm.dll" directly, please see:
http://www.dreamincode.net/forums/topic/45693-controlling-sound-volume-in-c%23/[^],
http://www.geekpedia.com/tutorial176_Get-and-set-the-wave-sound-volume.html[^].

See also this article: http://www.codeguru.com/csharp/csharp/cs_graphics/sound/article.php/c10931[^].

The above method still needs using P/Invoke. This is not very good.

You can use ready-to-use Microsoft .NET class Microsoft.DirectX.AudioVideoPlayback to work in pure managed code. Please see:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb324235%28v=vs.85%29.aspx[^].

—SA


首先,您发布的内容不是键盘挂钩.您只是在偷看某些键的状态.

第二,计时器是什么?您可能每秒要调用此键偷看"代码10次,但这并不能保证您会看到键状态的变化.

我会告诉您如何解决此问题,但这是不可修复的.认真地讲,这种方法永远行不通.您必须取消此操作并使用REAL键盘挂钩.只有这样,您才能吃掉"击键,使应用程序看不到它们.

开始阅读
First, what you posted is not a keyboard hook. You''re just peeking at the state of certain keys.

Second, what''s with the Timer?? You may be calling this "key peek" code 10 times a second, but that''s no guarantee you''re going to see a key state change.

I''d tell you how to fix this, but it''s not fixable. Seriously, this approach will never work. You have to scrap this and use a REAL keyboard hook. Only then will you gain the ability to "eat" the keystrokes so applications can''t see them.

Start reading these[^].


这篇关于需要取消钩住的按键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆