none
Fokus abgeben und SendKey RRS feed

  • Frage

  • Ich möchte gerne eine Bildschirmtastatur machen. Innerhalb der Form funktioniert alles, jedoch nicht wenn ich eine Textbox einer anderen Anwendung auswähle da ja der Fokus bei einem Klick auf einem Button auf die Tastatur springt.

     

    Auch hab ich das Problem mit SendKey da zum Beispiel bei         SendKeys.Send(Keys.Tab) passiert, liegt das am Fokus?

    Montag, 4. Oktober 2010 16:12

Alle Antworten

  • Hallo,

    Ich möchte gerne eine Bildschirmtastatur machen.

    welche herausragenden Eigenschaften soll denn Deine Bildschirmtastatur gegenüber der von Windows mitgelieferten haben?

    Innerhalb der Form funktioniert alles, jedoch nicht wenn ich eine Textbox einer anderen Anwendung auswähle da ja der Fokus bei einem Klick auf einem Button auf die Tastatur springt.

    Mit jedem Klick wandert der Fokus auf Dein Fenster, der SendKeys.Send Befehl landet also auch bei Deinem Fenster. Damit Deine Bildschirmtastatur ansatzweise funktioniert, musst Du zunächst das zuletzt aktive Fenster ermitteln und dieses aktivieren, bevor Du den SendKeys.Send Befehl absetzt. Ein möglicher Ansatz:

    Public Class Form1
    
     Private Sub ActivateNextWindow()
      Dim lLastWindow As IntPtr = Me.Handle
    
      Do
       lLastWindow = NativeMethods.GetWindow(lLastWindow, NativeMethods.GW.GW_HWNDNEXT)
      Loop Until NativeMethods.IsWindowVisible(lLastWindow)
    
      If lLastWindow <> IntPtr.Zero Then
       NativeMethods.SetForegroundWindow(lLastWindow)
      End If
     End Sub
    
     Private Sub Button1_Click(ByVal sender As System.Object, _
                  ByVal e As System.EventArgs) Handles Button1.Click
    
      ActivateNextWindow()
    
      SendKeys.Send("A")
     End Sub
    
     Private Class NativeMethods
      Friend Enum GW As UInteger
       GW_HWNDFIRST = 0
       GW_HWNDLAST = 1
       GW_HWNDNEXT = 2
       GW_HWNDPREV = 3
       GW_OWNER = 4
       GW_CHILD = 5
       GW_ENABLEDPOPUP = 6
      End Enum
    
      <DllImport("user32.dll", SetLastError:=True)> _
      Friend Shared Function GetWindow(ByVal hWnd As IntPtr, ByVal uCmd As GW) As IntPtr
      End Function
    
      <DllImport("user32.dll")> _
      Friend Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
      End Function
    
      <DllImport("user32.dll", SetLastError:=True)> _
      Friend Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
      End Function
     End Class
    End Class
    
    

    Die Windows Bildschirmlupe arbeitet gewiss noch etwas anders und bekommt erst gar nicht den Fokus bzw. aktiviert das fremde Fenster sofort wieder. Ferner arbeitet man hier auch nicht mit Buttons als Schaltflächen, sondern zeichnet das Tastaturlayout auf die Fläche und wertet den Klickbereich aus. Zumindest ist dies anzunehmen. Aber für den Anfang solltest Du einen Schritt weiterkommen.

    Auch hab ich das Problem mit SendKey da zum Beispiel bei         SendKeys.Send(Keys.Tab) passiert, liegt das am Fokus?

    Nein, das liegt nicht am Fokus, sondern in der falschen Anwendung der SendKeys.Send Methode. Diese erwartet einen String als Parameter und kein Member der Keys Aufzählung. Um die Tabulatortaste zu senden verwendest Du SendKeys.Send("{TAB}"). Bitte lies die Dokumentation zu SendKeys.Send, denn da ist das ausführlichst erläutert.


    Thorsten Dörfler
    Microsoft MVP Visual Basic
    vb-faq.de
    Montag, 4. Oktober 2010 17:18

  • Hallo Riwolfes,
    ein entsprechendes Beispiel bei dem SendKey.Send verwendet wird, sich das Programm aber zuvor das Fenster in den Vordergrund holt, das es benötigt, findest du hier:
    Public Class Form1
      ' Get a handle to an application window.
      Declare Auto Function FindWindow Lib "USER32.DLL" ( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String) As IntPtr
    
      ' Activate an application window.
      Declare Auto Function SetForegroundWindow Lib "USER32.DLL" _
        (ByVal hWnd As IntPtr) As Boolean
    
    
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Anwendung muss bereits gestartet sein !!! Nicht erst hier starten 
    
        '//Fenster suchen
        Dim myHandle As IntPtr = FindWindow("Notepad", "Unbenannt - Editor") '//Hier mit dem beliebiegen Fenstername austauschen
        ' Verify that Calculator is a running process.
    
        If myHandle = IntPtr.Zero Then
          MsgBox("Notepad nicht gestartet")
          Return
        End If
    
        ' Setzt die Anwendung in den Vordergrund und gibt die Werte ein 
        SetForegroundWindow(myHandle)
        SendKeys.SendWait("111")
        SendKeys.SendWait("*")
        SendKeys.SendWait("11")
        SendKeys.SendWait("=")
      End Sub
    
    
      Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        SetForegroundWindow(RichTextBox1.TextLength)
        RichTextBox1.Focus()
        SendKeys.SendWait("111")
        SendKeys.SendWait("*")
        SendKeys.SendWait("11")
        SendKeys.SendWait("=")
        SendKeys.Send("A")
        'SendKeys.Send("^{x}")
        SendKeys.Send("{ENTER}")
        SendKeys.Send("{ENTER}")
        SendKeys.Send("Ende")
    
      End Sub
    
      Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        SendKeys.SendWait("%{D}")
      End Sub
    
      Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        SendKeys.SendWait("%{P}")
      End Sub
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Process.Start("C:\WINDOWS\notepad.exe")
        Timer1.Enabled = True
      End Sub
    
      Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
        Process.Start("C:\WINDOWS\notepad.exe")
      End Sub
    
      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Timer1.Interval = 200
        Timer1.Enabled = True
        Dim myHandle As IntPtr = FindWindow("Notepad", "Unbenannt - Editor") '//Hier mit dem beliebiegen Fenstername austauschen
        'SendKeys.Send("^{x}")
        SendKeys.SendWait("D")
        SendKeys.SendWait("A")
        SendKeys.SendWait("S")
        SendKeys.Send(" ")
        SendKeys.SendWait("I")
        SendKeys.SendWait("S")
        SendKeys.SendWait("T")
        SendKeys.Send("{ENTER}")
        SendKeys.SendWait("ein")
        SendKeys.Send(" ")
        SendKeys.Send("Test")
        SendKeys.Send("{ENTER}")
        SendKeys.Send("Ende")
      End Sub
    End Class
    
    


    Liebe Grüße Stefan | Cheers Stefan I'm using VB 2008 Express
    Donnerstag, 21. Oktober 2010 15:16