Zugriff auf externes Programm
-
Hi Leute!
Ich habe ein kleines Problem, ich habe mir ein Programm mit Visual Basic geschrieben, welches aus einem anderen Programm Nachrichten, welche an eine Unterklasse des Programms gesendet werden abfängt und ausliesst.
Ich würde das ganze gerne in C++ codieren, jedoch habe ich nicht so die Ahnung, wie ich vernünftig die API in C++ einsetzen kann, ich hab zwar schon ein paar nette Funktionen kennen gelernt bin aber nicht weiter gekommen.
Erst einmal kurz zur Problemstellung: mein Programm sollte anhand des Fenstertitels das andere Programm(auf das ich zugreifen möchte) ausfindig machen und das Fenster Handel feststellen, dass ich damit arbeiten kann.
Danach möchte ich auf ein Childfenster des Programms zugreifen (Ein Richedit Fenster, welches ständig Nachrichten des Programms anzeigt). Ich möchte diese Nachrichten auslesen in eine Variable und diese Strings weiter verarbeiten.
Diese Strings sollen mit festen Werten verglichen werden um daraufhin (wenn die Werte übereinstimmen) eine Variable um 1 Zählerpunkt zu erhöhen. Es soll also etwas gezählt werden, was an Text in dem Richedit Fenster in dem Programm, von dem ich nur den Titel kenne, ausgegeben wird. Mit Visual Basic war das ganze sehr einfach, ist aber auch sehr sehr langsam und überhaupt nicht zu gebrauchen!
Ich kenne mich auch mit C++ aus, jedoch habe ich noch nie bisher ein solches Projekt mit C++ umgesetzt. Meine Frage ist ganz einfach, kennt jemand eine relativ simple Lösung in C++ für mein Problem. Ich muss dazu sagen ich habe bisher noch keine großartigen Anwendungen in C++ für Windows geschrieben, sondern immer nur Konsolen Anwendungen, die aber auch schon recht umfangreich waren.Als kleine Hilfe ein paar Funktionen, die ich für den Zugriff auf das Richedit Fenster in VB verwendet habe: EM_LINESCROLL; EM_GETLINE; EM_GETLINECOUNT; WM_GETTEXTLENGTH oder EM_GETTEXTLENGTH...
Vielen Dank für Eure Hilfe
LG
Boris
-
Wenn Dein Programm nichts mehr macht, als nur Daten in dem fremden Programm auszulesenund selbst sonst nichts tut (jedenfalls nichts zeitintensives), dann ist kaum zu erwarten, dass ein C++ Programm schneller ist.
Das Problem ist hier die Interprozesskommunikation und wie schnell die andere Aplikation Deine Nachricht bearbeitet., sprich wie oft diese die Nachrichtenschleife abarbeitet.
-
Hi Martin,
danke für deine prompte Antwort, weisst du, wie ich die Interprozesskommunikation verbessern kann? Als Hilfe stelle ich hier mal den Code von meinem VB-Programm hier rein (hat hier zwar nix zu suchen, aber vl. kann ja jemand sagen, woran es liegt, dann wäre mir ja schon geholfen).
Code:
'Das ist das Modul, welches ich in meinem Programm verwende... Option Explicit Declare Function EnumChildWindows Lib "user32" (ByVal _ hWndParent As Long, ByVal lpEnumFunc As Long, ByVal _ lParam As Long) As Long Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam _ As Long, lParam As Any) As Long Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _ (ByVal hwnd As Long, ByVal lpClassName As String, ByVal _ nMaxCount As Long) As Long Const WM_GETTEXT = &HD Const WM_GETTEXTLENGTH = &HE Const EM_GETLINECOUNT = &HBA Const EM_GETLINE = &HC4 Dim zaehler As Integer, lline1 As Long Public Function EnumChildProc(ByVal hwnd As Long, ByVal lParam As Long) As Long Dim a As String, b As String, g As String, l As Long, length As Long, lline As Long length = SendMessage(hwnd, WM_GETTEXTLENGTH, ByVal 0, ByVal 0) lline = SendMessage(hwnd, EM_GETLINECOUNT, ByVal 0, ByVal 0) a = Space$(length) l = GetClassName(hwnd, a, 128) g = Left(a, l) If g = "RICHEDIT" Then If Not lline = lline1 Then lline1 = lline Form1.Label3.Caption = lline l = SendMessage(hwnd, EM_GETLINE, ByVal lline - 1, ByVal a) b = Left(a, l - 2) If g = "RICHEDIT" Then Form1.Text1.Text = Left(a, l) If b = "zu vergleichender Text... " Then zaehler = zaehler + 1 End If Form1.Label4.Caption = zaehler End If End If EnumChildProc = 1 End Function 'Hier kommt die Form1, mit den Objekten: Timer1, Label2, Text1, Label3 und Label4 Option Explicit Private Declare Function FindWindow Lib "user32" Alias _ "FindWindowA" (ByVal lpClassName As String, ByVal _ lpWindowName As String) As Long Dim F As Long Private Sub Form_Load() Timer1.Interval = 1 End Sub Private Sub Timer1_Timer() F = FindWindow("Anwendungstitel", vbNullString) Label2.Caption = Str$(F) EnumChildWindows F, AddressOf EnumChildProc, ByVal 0& End Sub
-
Es geht im Prinzip genau gleich wie in deinem VB Programm, die ganzen Funktionen die du dort verwendest kannst du 1:1 auch mit C++ verwenden.
Einzige Ausnahme ist "Form1". Wenn das C++ Programm ein Fenster haben soll musst du eben mit Win32/MFC/... ein Fenster aufmachen, ansonsten kannst du die Daten auch einfach auf die Konsole rausschreiben.Die ganzen "Declare Function" brauchst du in C++ auch nicht, die "Const" genausowenig, stattdessen inkludierst du einfach die windows.h.