Auf ein Control von einem anderen Programm zugreifen

  • VB.NET

Es gibt 28 Antworten in diesem Thema. Der letzte Beitrag () ist von xaverl.

    Ich kann bisher nur Inhalt hinzufügen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal nVirtKey As Keys) As Short
    3. Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    4. Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWndParent As Integer, ByVal hWndChildAfter As Integer, ByVal lpszClass As String, ByVal lpszWindow As String) As Integer
    5. Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    6. Private Const WM_CHAR As Integer = &H102
    7. Private hwnd As IntPtr
    8. Private f As IntPtr
    9. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    10. hwnd = FindWindow(vbNullString, "Unbenannt - Editor")
    11. f = FindWindowEx(hwnd, 0, "Edit", vbNullString)
    12. End Sub
    13. Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
    14. SendMessage(f, WM_CHAR, Asc(e.KeyChar), 0)
    15. End Sub
    16. End Class


    getestet mit dem Editor. Aber ich will es eigentl. genau anders rum!

    Lg Leon
    Aaaach, heut gibts sources umsonst, was soll der Geiz...

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Declare Function SendMessageByString Lib "user32.dll" Alias _
    3. "SendMessageA" _
    4. (ByVal hwnd As IntPtr, _
    5. ByVal uMsg As Int32, _
    6. ByVal wParam As IntPtr, _
    7. ByVal lParam As String) As Integer
    8. Private Const WM_SETTEXT As Int32 = &HC
    9. Private Const WM_GETTEXT As Int32 = &HD
    10. Private Declare Function SendMessageByInt Lib "user32.dll" Alias _
    11. "SendMessageA" _
    12. (ByVal hwnd As IntPtr, _
    13. ByVal uMsg As Int32, _
    14. ByVal wParam As Int32, _
    15. ByVal lParam As Int32) As Integer
    16. Private Const WM_GETTEXTLENGTH As Int32 = &HE
    17. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
    18. (ByVal lpClassName As String, _
    19. ByVal lpWindowName As String) As IntPtr
    20. Private Declare Function FindWindowEx Lib "user32.dll" Alias _
    21. "FindWindowExA" _
    22. (ByVal hWnd1 As IntPtr, _
    23. ByVal hWnd2 As IntPtr, _
    24. ByVal lpsz1 As String, _
    25. ByVal lpsz2 As String) As IntPtr
    26. <Runtime.InteropServices.DllImport("user32.dll")> _
    27. Private Shared Function SendMessage( _
    28. ByVal hWnd As IntPtr, _
    29. ByVal Msg As Integer, _
    30. ByVal wParam As Integer, _
    31. ByVal lParam As System.Text.StringBuilder) _
    32. As Integer
    33. End Function
    34. Public Function GetHandle(ByVal ClassName As String) As IntPtr
    35. Dim hwnd As IntPtr = FindWindow(ClassName, Nothing)
    36. hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Edit", Nothing)
    37. If (Not hwnd.Equals(IntPtr.Zero)) Then
    38. Return hwnd
    39. Else
    40. Return IntPtr.Zero
    41. End If
    42. End Function
    43. Public Sub SetNewText(ByVal hwnd As IntPtr, ByVal txt As String)
    44. If (Not hwnd.Equals(IntPtr.Zero)) Then
    45. Call SendMessageByString(hwnd, WM_SETTEXT, IntPtr.Zero, txt)
    46. End If
    47. End Sub
    48. Public Function GetNewText(ByVal hwnd As IntPtr) As String
    49. If (Not hwnd.Equals(IntPtr.Zero)) Then
    50. Dim SB As New System.Text.StringBuilder
    51. Dim BufferSize As Integer = 32768
    52. SB.EnsureCapacity(BufferSize)
    53. SendMessage(hwnd, WM_GETTEXT, BufferSize, SB)
    54. Return SB.ToString
    55. Else
    56. Return ""
    57. End If
    58. End Function
    59. Public Function GetTextLength(ByVal hwnd As IntPtr) As Integer
    60. If (Not hwnd.Equals(IntPtr.Zero)) Then
    61. Dim Length As Integer = SendMessageByInt(hwnd, WM_GETTEXTLENGTH, 0, _
    62. 0)
    63. If Length > 0 Then
    64. Return Length
    65. Else
    66. Return 0
    67. End If
    68. End If
    69. End Function
    70. Private Sub Button1Click(ByVal sender As System.Object, ByVal e As _
    71. System.EventArgs) Handles Button1.Click
    72. Dim hwnd As IntPtr = GetHandle("Notepad")
    73. If (Not hwnd.Equals(IntPtr.Zero)) Then
    74. 'Call SetNewText(hwnd, "http://www.visual-basic5.de")
    75. MsgBox(GetNewText(hwnd))
    76. Else
    77. MessageBox.Show("Notepad not found...", "Info")
    78. End If
    79. End Sub
    80. End Class


    credits visual-basic5.de
    Für ein Mindestmaß an Rechtschreibung, Interpunktion und Majuskeln!
    Hallo,

    ich kämpfe mich mit einem ähnlichen Problem rum wie Halfbax.
    Ich habe versucht den Code von bla auf mich umzuschreiben (Visual Studio 2010) und das SetText habe ich weggelassen.

    Jetzt bekomme ich immer die Messagebox angezeigt Notepad not found.
    Jetzt wollt ich euch fragen ob er dann den Frame nicht findet, aus dem ich Daten haben will?

    Danke
    Ich will die Daten aus einem anderen Programm auslesen und verwende natürlich die Classennamen von diesem Programm.
    Ich poste dir schnell deinen Code so wie ich ihn momentan habe.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Declare Function SendMessageByString Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    2. 'Private Const WM_SETTEXT As Integer = &HC
    3. Private Const WM_GETTEXT As Integer = &HD
    4. Private iHwndForm As IntPtr
    5. 'Fensterhanlde ermitteln
    6. Private iHwndFrame As IntPtr
    7. Private Declare Function SendMessageByInt Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    8. Private Const WM_GETTEXTLENGTH As Integer = &HE
    9. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    10. Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
    11. <Runtime.InteropServices.DllImport("user32.dll")>
    12. Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As Integer
    13. End Function
    14. Public Function GetHandle(ByVal ClassName As String) As IntPtr
    15. Dim hwnd As IntPtr = FindWindow("Migg", "ThunderRT6FormDC")
    16. hwnd = FindWindowEx(hwnd, 0, "ThunderRT6Frame", "Messungsergebnis")
    17. If (Not hwnd.Equals(IntPtr.Zero)) Then
    18. Return hwnd
    19. Else
    20. Return 0
    21. End If
    22. End Function
    23. 'Public Sub SetNewText(ByVal hwnd As IntPtr, ByVal txt As String)
    24. ' If (Not hwnd.Equals(IntPtr.Zero)) Then
    25. ' Call SendMessageByString(hwnd, WM_SETTEXT, 0, txt)
    26. ' End If
    27. 'End Sub
    28.  
    29. Public Function GetNewText(ByVal hwnd As IntPtr) As String
    30. If (Not hwnd.Equals(IntPtr.Zero)) Then
    31. Dim SB As New System.Text.StringBuilder
    32. Dim BufferSize As Integer = 32768
    33. SB.EnsureCapacity(BufferSize)
    34. SendMessage(hwnd, WM_GETTEXT, BufferSize, SB)Return SB.ToString
    35. Else
    36. Return ""
    37. End If
    38. End Function
    39. Public Function GetTextLength(ByVal hwnd As IntPtr) As Integer
    40. If (Not hwnd.Equals(IntPtr.Zero)) Then
    41. Dim Length As Integer = SendMessageByInt(hwnd, WM_GETTEXTLENGTH, 0, 0)
    42. If Length > 0 Then
    43. Return Length
    44. Else
    45. Return 0
    46. End If
    47. End If
    48. End Function
    49. Private Sub Button1Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    50. ''Fenster Handle ermitteln
    51. 'iHwndForm = FindWindow(vbNullString, "Migg")
    52. ''Button Handle ermitteln
    53. 'iHwndFrame = FindWindowEx(iHwndForm, 0, "ThunderRT6Frame", "Messungsergebnis")
    54. 'MsgBox(GetNewText("Messungsergebnis"))
    55.  
    56.  Dim hwnd As IntPtr = GetHandle("Messungsergebnis")
    57. If (Not hwnd.Equals(IntPtr.Zero)) Then
    58. 'Call SetNewText(hwnd, "http://www.visual-basic5.de")
    59. MsgBox(GetNewText(hwnd))
    60. Else
    61. MessageBox.Show("Wo sind die verdammten Zahlen")
    62. End If
    63. End Sub
    64. End Class
    Nach langen rumprobieren bin ich jetzt auf das Problem gestoßen.
    Es ist das FindWindowEx da ich damit nur direkte ChildWindows ansprechen kann und der Frame den ich ansprechen will ist jetzt eine Hirachieebene drunter. Weiß jemand mit welcher Funktion man "vererbte Childwindows" ansprechen kann.

    Danke

    VB.NET-Quellcode

    1. Private Sub Button1Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Dim hwnd As IntPtr '= GetHandle("Messungsergebnis")
    3. Dim childwindow1, childwindow2 As intptr
    4. hwnd = FindWindow("ThunderRT6FormDC", "Migg")
    5. childwindow1 = FindWindowEx(hwnd, 0, "ThunderRT6PictureBoxDC", "")
    6. childwindow2 = FindWindowEx(childwindow1, 0, "ThunderRT6Frame", "Messungsergebnis")
    7. 'If (Not hwndFrame.Equals(IntPtr.Zero)) Then
    8. DataGridView1.Rows(0).Cells(0).Value = (GetNewText(childwindow2))


    Ich hab jetzt bei meinem hwnd und bei meinem childwindow1 einen Wert.
    Bei meinem childwindow2 erhalte ich immer noch keinen Wert.

    Mein Problem ist jetzt, dass ich von den ThunderRT6PictureBoxDC 4 Stück habe und die die ich brauch ist die 3. aber ich denke mein Programm steuert immer die 1. an. Über den WindowNamen kann ich es leider nicht ansteuern weil alle 4 Pictureboxen keinen Namen haben.
    ich glaube, wenn es die 3. Picturebox ist, dann musst du 3 mal findwindowex machen. Bin mir aber nicht sicher. Also quasi:

    VB.NET-Quellcode

    1. childwindow1 = FindWindowEx(hwnd, 0, "ThunderRT6PictureBoxDC", "")
    2. childwindow1 = FindWindowEx(hwnd, 0, "ThunderRT6PictureBoxDC", "")
    3. childwindow1 = FindWindowEx(hwnd, 0, "ThunderRT6PictureBoxDC", "")
    4. childwindow2 = FindWindowEx(childwindow1, 0, "ThunderRT6Frame", "Messungsergebnis")
    Für ein Mindestmaß an Rechtschreibung, Interpunktion und Majuskeln!
    Ich habs gerade ausprobiert und es geht leider nicht.
    Jetzt hab ich mal eine Frage:

    VB.NET-Quellcode

    1. HWND WINAPI FindWindowEx(in_opt HWND hwndParent, in_opt HWND hwndChildAfter, in_opt LPCTSTR lpszClass, in_opt LPCTSTR lpszWindow);


    Da heißt es jetzt in der msdn Beschreibung das der Teil "in_opt HWND hwndChildAfter" wenn er null ist in mit dem ersten Childwindow beginnt. Kann ich dem jetzt irgendwie sagen beginn erst mit dem dritten?
    Das erste Fenster findest Du mit

    VB.NET-Quellcode

    1. _hwndInput = FindWindowEx(_hwndMain, IntPtr.Zero, "edit", "")

    das nächste mit

    VB.NET-Quellcode

    1. _hwndInput2 = FindWindowEx(_hwndMain, _hwndInput, "edit", "")

    das übernächste mit

    VB.NET-Quellcode

    1. _hwndInput3 = FindWindowEx(_hwndMain, _hwndInput2, "edit", "")

    usw.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!