Keypress Problem


Hallo,
ich habe ein schon seit gestern mit folgendem Problem zu kämpfen: Ich bekomme mein Programm zwar so gecodet, dass es den Prozess (hier als Beispiel Taskmanager) per ButtonKlick beendet. Ich habe bereits vieles versucht, aber ich schaffe es nicht, den Private Sub Button2_Click mit einem KeyPress oder KeyDown mit der Taste Escape zu ersetzen. Könnte mir evtl jemand helfen? Hier der Code:
Code:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Close()
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        For Each Process In System.Diagnostics.Process.GetProcessesByName("taskmgr")
            Process.Kill()
        Next
    End Sub
End Class
 

Shakie

Erfahrenes Mitglied
Möglichkeit 1:
Du setzt die CancelButton-Eigenschaft der Form auf Button1 - damit wird die PerformClick-Methode des Buttons ausgeführt, wenn die Escape-Taste gedrückt wird.
Code:
Me.CancelButton = Me.Button1 ' kannst du auch im Designer einstellen
Möglichkeit 2:
Du verwendest das KeyDown/KeyUp-Event und setzt die Eigenschaft KeyPreview auf true:
Code:
Me.KeyPreview = True

Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
    If e.KeyCode = Keys.Escape Then Me.Close()
End Sub
 
EDIT: Funktioniert mittlerweile. Habe <KeyPreview> einfach im Designer auf True gesetzt. Jedoch habe ich folgendes Problem: Das Programm beendet den Prozess "taskmgr", solange mein geschriebenes Programm im Vordergrund ist. Da mein Programm für ein Spiel gedacht ist, geht das schlecht, da das Spiel ja dann im Vordergrund ist und im Falle eines Freezes dann per Taste beendet werden kann. Ich habe bereits eine Lösung gefunden, VS zeigt keine Fehler an, leider erscheint beim Debuggen dann die Meldung "Win32exception wurde nicht behandelt - Fehler beim Erstellen des Fensterhandles." Eine Lösung finde ich auch per Google nicht. Hat jemand eine Idee? Hier nochmal der gesamte Code:
Code:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Close()
    End Sub
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        If m.Msg = Keys.F9 Then
            Me.Show()
        End If
    End Sub
    Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        If e.KeyCode = Keys.F9 Then
            For Each Process In System.Diagnostics.Process.GetProcessesByName("taskmgr")
                Process.Kill()
            Next
        End If
    End Sub
End Class
 
Zuletzt bearbeitet:

Shakie

Erfahrenes Mitglied
Kann das jetzt nicht unbedingt nachvollziehen, aber du solltest auch die WndProc-Methode der überschriebenen Klasse aufrufen, falls du nicht alle Nachrichten behandeln willst. Außerdem überprüfst du nicht, ob es sich bei der empfangenen Nachricht wirklich um einen Tastendruck handelt, sondern du überprüfst jede Nachricht unabhängig vom Typ ob sie zufällig den Wert Cint(Keys.F9) hat.
Also besser irgendwie sowas:
Code:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    If (m ist eine Tastendruck-Nachricht) AND (m.Msg = Keys.F9) Then
        Me.Show()
    Else
        MyBase.WndProc(m)
    End If
End Sub
Außerdem sehe ich noch nicht warum du die WndProc der Form überhaupt überschreiben willst. Wenn die Form nicht den Fokus hat wird der F9-Tastendruck auch niemals bei ihr ankommen. Ich denke du müsstest da einen globalen Hook verwenden um auf alleTastendrücke reagieren zu können.
 
Hallo Shakie,
tut mir leid, mein Fehler. Hatte da irgendetwas durcheinandergebracht. Wollte ja zuerst soweit kommen, dass wenn das Prog minimiert ist, er sich auf Tastendruck wiederherstellt. Funktioniert aber auch nicht, da das Programm eben wieder nciht den Befehl 'mitkriegt' weil es nicht aktiv ist. So sieht also mein Code aus
Code:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Close()
    End Sub
    Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        If e.KeyCode = Keys.F9 Then
            'Programm muss auch im Hintergrund auf den Tastendruck reagieren.
            For Each Process In System.Diagnostics.Process.GetProcessesByName("taskmgr")
                Process.Kill()
            Next
        End If
    End Sub
End Class
Hier fehlt jetzt noch die bestimmte Zeile, dass er die Befehle abruft, auch wenn das Prog nicht im Vordergrund ist.
Die bräuchte eigentlich nur, denn das Programm funktioniert so ja spitze, leider nur im Vordergrund.
 
Danke für die Lösung. Habe jetzt bereits schon eine andere Lösung, die funktioneirt eig. auch. Wenn ich das ganze für den Prozess taskmgr teste, dann funktioniert alles prima. Probiere ich das Prog bei einem Spiel spuckt er mir beim Drücken der F9 Taste einen .Net Framework Fehler aus, "Unbehandelte Ausnahme".
Hier der Code:
Code:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Close()
    End Sub
    Private Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Integer
    Private Declare Sub UnregisterHotKey Lib "user32" (ByVal hWnd As IntPtr, ByVal id As Integer)
    Private Const Key_NONE As Integer = &H0
    Private Const WM_HOTKEY As Integer = &H312

    Protected Overrides Sub WndProc(ByRef m As Message)
        If m.Msg = WM_HOTKEY Then
            Select Case m.WParam
                Case 1
                    For Each Process In System.Diagnostics.Process.GetProcessesByName("Warrock")
                        Process.Kill()
                    Next
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'die F9 Taste wieder freigeben
        UnregisterHotKey(Me.Handle, 1)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'die F9 Taste abfangen
        RegisterHotKey(Me.Handle, 1, Key_NONE, Keys.F9)
    End Sub
End Class
 
Was meinst du genau? Ganz einfach: Auch wenn das Prog im Hintergrund läuft soll es den Tastendruck ( in meinem Fall F9 ) die Anweisung (Prozess beenden) ausführen.

MfG
 
Das hier spuckt er aus:
Code:
Informationen über das Aufrufen von JIT-Debuggen
anstelle dieses Dialogfelds finden Sie am Ende dieser Meldung.

************** Ausnahmetext **************
System.ComponentModel.Win32Exception (0x80004005): Zugriff verweigert
   bei System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
   bei System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
   bei System.Diagnostics.Process.Kill()
   bei WindowsApplication1.Form1.WndProc(Message& m)
   bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Geladene Assemblys **************
mscorlib
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 (RTMRel.030319-0100).
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll.
----------------------------------------
XIII Process Killer
    Assembly-Version: 1.0.0.0.
    Win32-Version: 1.0.0.0.
    CodeBase: file:///C:/Users/Rahul/Desktop/XIII%20Process%20Killer.exe.
----------------------------------------
Microsoft.VisualBasic
    Assembly-Version: 10.0.0.0.
    Win32-Version: 10.0.30319.1 built by: RTMRel.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic/v4.0_10.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll.
----------------------------------------
System
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 built by: RTMRel.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll.
----------------------------------------
System.Core
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 built by: RTMRel.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll.
----------------------------------------
System.Windows.Forms
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 built by: RTMRel.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll.
----------------------------------------
System.Drawing
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 built by: RTMRel.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll.
----------------------------------------
System.Configuration
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 (RTMRel.030319-0100).
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll.
----------------------------------------
System.Xml
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 built by: RTMRel.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll.
----------------------------------------
System.Runtime.Remoting
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 (RTMRel.030319-0100).
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll.
----------------------------------------
System.Windows.Forms.resources
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 built by: RTMRel.
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0.0_de_b77a5c561934e089/System.Windows.Forms.resources.dll.
----------------------------------------
mscorlib.resources
    Assembly-Version: 4.0.0.0.
    Win32-Version: 4.0.30319.1 (RTMRel.030319-0100).
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/mscorlib.resources/v4.0_4.0.0.0_de_b77a5c561934e089/mscorlib.resources.dll.
----------------------------------------

************** JIT-Debuggen **************
Um das JIT-Debuggen (Just-In-Time) zu aktivieren, muss in der
Konfigurationsdatei der Anwendung oder des Computers
(machine.config) der jitDebugging-Wert im Abschnitt system.windows.forms festgelegt werden.
Die Anwendung muss mit aktiviertem Debuggen kompiliert werden.

Zum Beispiel:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

Wenn das JIT-Debuggen aktiviert ist, werden alle nicht behandelten
Ausnahmen an den JIT-Debugger gesendet, der auf dem
Computer registriert ist, und nicht in diesem Dialogfeld behandelt.
 

Cromon

Erfahrenes Mitglied
Es steht doch hier ganz klar, was das Problem ist ;)
System.ComponentModel.Win32Exception (0x80004005): Zugriff verweigert

Versuch mal ob es geht, wenn du den Debugmodus betrittst mit deinem Prozess. Also vorher
Code:
System.Diagnostics.Process.EnterDebugMode();

aufrufen.
 

Cromon

Erfahrenes Mitglied
Dein Prozess muss bevor er auf andere geschützte Prozesse zugreiffen will das SE_DEBUG-Privileg bekommen. Das geschieht über EnterDebugMode. Wo das dann in deinem Code genau ist musst du schon selbst herausfinden ;)
 
Funktioniert leider immernoch nicht. Hier der Code, wie er derziet aussieht.
Code:
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Me.Close()
    End Sub
    Private Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Integer
    Private Declare Sub UnregisterHotKey Lib "user32" (ByVal hWnd As IntPtr, ByVal id As Integer)
    Private Const Key_NONE As Integer = &H0
    Private Const WM_HOTKEY As Integer = &H312

    Protected Overrides Sub WndProc(ByRef m As Message)
        System.Diagnostics.Process.EnterDebugMode()
        If m.Msg = WM_HOTKEY Then
            Select Case m.WParam
                Case 1
                    For Each Process In System.Diagnostics.Process.GetProcessesByName("Warrock")
                        Process.Kill()
                    Next
            End Select
        End If
        MyBase.WndProc(m)
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        'die F9 Taste wieder freigeben
        UnregisterHotKey(Me.Handle, 1)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'die F9 Taste abfangen
        RegisterHotKey(Me.Handle, 1, Key_NONE, Keys.F9)
    End Sub
End Class
 

Neue Beiträge

Forum-Statistiken

Themen
272.360
Beiträge
1.558.622
Mitglieder
187.833
Neuestes Mitglied
SirrDansen