SendMessage Problem

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von hal2000.

    SendMessage Problem

    Hi,

    frohes Neues an alle ^^

    ich hab ein Problem. Ich muss ein anderes Programm fernsteuern. Eigentlich wollte ich paramter über die commandline übergeben aber das geht nicht

    jetzt starte ich das andere programm mit

    VB.NET-Quellcode

    1. Dim atscwinStartInfo As New ProcessStartInfo
    2. atscwinStartInfo.FileName = "C:\Dokumente und Einstellungen\msv\Desktop\blabla.exe"
    3. atscwinStartInfo.CreateNoWindow = True
    4. atscwin = New Process
    5. atscwin.StartInfo = atscwinStartInfo
    6. atscwin.Start()


    leider funktioniert CreateNoWindow oder WindowsStyle.Hidden / Minimized nicht ... das ding reagiert einfach nicht darauf ... egal habe mein programm auf TopMost = True gestellt. ( sowieso ein riesengroßer pfusch das ganze )

    so jetzt möchte ich gerne mit SendMessage "ALT + D " an das andere Programm schicken ... wie mache ich das?

    WindowsHandle habe ich über atscwin.MainWindowHandle
    Zunächst kannst Du obigen Code auch so schreiben:

    VB.NET-Quellcode

    1. Dim atscwin = New Process
    2. atscwin.StartInfo.FileName = "C:\Dokumente und Einstellungen\msv\Desktop\blabla.exe"
    3. atscwin.StartInfo.CreateNoWindow = True
    4. atscwin.Start()
    Teste zunächst, ob Du mit SendKeys Deine Informationen richtig zu dem Programm rüberbringst (dazu muss es den Fokus haben).
    Wenn das klappt, geht SendMessage() problemlos.
    Wenn nicht, kann es sein, dass Du ein bestimmtes Client-Fenster als Zielfenster benötigst.
    Dann wird es etwas umständlicher, mit EnumerateWindows, FindWindow, FindWindowEx und Co, suche danach im Forum.
    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!
    also die dumme API kacke geht mir jetzt schon gegen den strich ...

    habe gerade mal versucht die child handels eines handels zu bekommen aber das will ja mal gar nicht ... nichts als fehler ...

    warum gibt GetWindowTextLength eine zahl zurück welche im 8 oder 9 stelligen bereich liegt? Ist das ein Pointer auf ne speicheradresse oder die tatsächliche länge?

    Weil bei der Zeile Title = Space$(result) bleibt das ganze stehen mit einer überlauf Exception ... ich denke dass man in einen String nicht Milliarden von leerzeichen schreiben kann ...

    kann mir das einer erklären?

    VB.NET-Quellcode

    1. Private Declare Function GetWindowTextLength Lib "User32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
    2. Private Declare Function GetWindowText Lib "User32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    3. Private Declare Function GetWindow Lib "User32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
    4. Private Declare Function IsWindowVisible Lib "User32" (ByVal hwnd As Long) As Long
    5. Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
    6. Private Const GW_HWNDFIRST = 0
    7. 'Returns all visible windowcaption in an array
    8. Public Function EnumerateWindows() As List(Of String)
    9. Dim hwnd As Long
    10. Dim result As Long
    11. Dim Title As String
    12. Dim res_list As New List(Of String)
    13. hwnd = GetWindow(GetForegroundWindow, GW_HWNDFIRST)
    14. Do
    15. If IsWindowVisible(hwnd) <> 0 Then
    16. result = GetWindowTextLength(hwnd) + 1
    17. Title = Space$(result)
    18. result = GetWindowText(hwnd, Title, result)
    19. Title = Mid(Title, 1, Len(Title) - 1)
    20. If Title <> "" Then
    21. res_list.Add(Title)
    22. End If
    23. End If
    24. hwnd = GetWindow(hwnd, GW_HWNDNEXT)
    25. Loop Until hwnd = 0
    26. Return res_list
    27. End Function


    ________________________________________________________________________________


    so bin wieder da ... war snowboarden ^^ jetzt kanns weiter gehn

    also das mit dem unterfenster könnte sein ... wwenn ich das ganze mal mit notepad teste dann bekomm ich das mainwindowshandle schön ausgeliefert ... das windowsfinder_demo teil was im netz herumschwirrt sagt das gleiche.
    bei dem programm welches ich steuern muss ist das allerdings nicht so ... warum kann nicht alles so schön wie notepad reagieren ... da geht sogar windowstyle.hidden ^^

    ich schau mal ob ich den/der/das handle bekomme ^^

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „_PASCAL_“ ()

    Starte mal den Spy++ und sieh Die an, was der zu Deinem Zielfenster sagt.
    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!

    _PASCAL_ schrieb:

    kann mir das einer erklären?

    alle deine Api-Deklarationen scheinen von vb6 kopiert zu sein, wo Long noch 32 bits long war.
    Inzwischen ist Long ja 64 bits long, oder sogar 128 bits - man weißes bald ja garnimmer.

    Aber Int32 - da wird man immer wissen, wieviele bits das sind ;)

    ups - zu spät - ja - pinvoke gute idee.
    was bedeutet "SendWait("%(v)")" ... das zu steuernde programm ist etwas eigen und wirft am anfang immer eine fehlermeldung egal was man auf der tastatur drückt ... das alte programm in VB6 hat die anscheined so behoben ... aber was ist das ...


    SetForeGroundWindow geht und auch EnumWindow ... EnumWindowChildren ergibt 0 was ja schonmal gut ist ... bei excel ergab es um die 38 ^^

    das geht allerdings nicht !

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. SetForegroundWindow(atscwin.MainWindowHandle)
    3. SendKeys.SendWait(Keys.F4)
    4. End Sub


    das fenster wird zwar aktiv gesetzt aber F4 wird nicht ausgeführt

    --------------------------------------------------
    old

    Danke ... ich werde danach schauen ... ich muss das problem echt lösen sonst bekomm ich hier ganz schön schwierigkeiten ...

    mit Spy++ kann ich nicht arbeiten da ich nur VBExpress hab da is das nicht dabei ... hmm doof ... hab nur das Spy++ von VB6 aber das blick ich nicht ganz ...

    ich habe zum visuellen handle zu bekommen das WindowFinder_demo genommen ... damit seh ich aber keine tastendrücke bekomm nur den handle

    im anhang mal ein bild der anwendung welche gesteuert werden soll ... jetzt müsste ein F4 danach F5 gedückt werden ... dann speichern und den process killen.

    aber ich bekomms ja nicht mal gebacken an notepad ein STRG + S zu schicken ... omg
    Bilder
    • atsc.JPG

      83,52 kB, 1.280×1.024, 135 mal angesehen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „_PASCAL_“ ()

    ja das beispiel habe ich mir schon angeschaut und habe auch daraf aufgebaut ...

    das doofe ist dass beim öffnen des programms welches ich steuern muss ( BildAnhang letzter post ) liegt der focus auf dem GridView ... und dieses verursacht bei jedem tastendruck eine fehlermeldung "Index auserhalb des gültigen bereiches" ... deshalb muss ich erst den focus von dem gridview bekommen dass ich mein "Alt - S" absetzen kann um an die Tabs zu kommen.

    Könnt ihr mir da iwie helfen ?
    Ich hab jetzt herausgefunden dass das Handle welches ich über proc.MainWindowHandle bekomme das falsche ist ... hat ja schon einmal jemand vermutet ... aber damals hat das ja ausgesehen als wäre das richtig ... in Spy++ hab ich dann gesehen dass es nicht so ist ... das handle welches ich hatte war ein TMainApplicaion Class handle welches keine childHandels hatte also mal total das falsche war ... jetzt hab ich def das richtige ... nur das sendMessage problem hab ich immernoch :(

    ---------------------------------------
    old

    Guten Morgen,

    ich hab jetzt mal mit Spy++ genau die events mitgeschnitten welche ausgelöst werden wenn ich "ALT + V" drücke ... leider weis ich jetzt nicht genau wie ich das deuten soll ...

    <00031> 00080174 S message:0x0092 [Unbekannt] wParam:00000000 lParam:0012F990
    <00032> 00080174 R message:0x0092 [Unbekannt] lResult:00000000
    <00033> 00080174 S message:0x0092 [Unbekannt] wParam:00000000 lParam:0012F990
    <00034> 00080174 R message:0x0092 [Unbekannt] lResult:00000000
    <00035> 00080174 S message:0x0092 [Unbekannt] wParam:00000000 lParam:0012F990
    <00036> 00080174 R message:0x0092 [Unbekannt] lResult:00000000
    <00037> 00080174 S message:0x0092 [Unbekannt] wParam:00000000 lParam:0012F990
    <00038> 00080174 R message:0x0092 [Unbekannt] lResult:00000000
    <00039> 00080174 S WM_WINDOWPOSCHANGING lpwp:0012F704
    <00040> 00080174 S WM_GETMINMAXINFO lpmmi:0012F17C
    <00041> 00080174 R WM_GETMINMAXINFO lpmmi:0012F17C
    <00042> 00080174 R WM_WINDOWPOSCHANGING
    <00043> 00080174 S WM_WINDOWPOSCHANGING lpwp:0012F704
    <00044> 00080174 S WM_GETMINMAXINFO lpmmi:0012F17C
    <00045> 00080174 R WM_GETMINMAXINFO lpmmi:0012F17C
    <00046> 00080174 R WM_WINDOWPOSCHANGING
    <00047> 00080174 S WM_NOTIFY idCtrl:262876 pnmh:0012F824
    <00048> 00080174 R WM_NOTIFY


    was ist daran jetzt "ALT" bzw "V" ... ist "0x0092" = ALT ?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „_PASCAL_“ ()

    Und ich würde mir je nachdem was das für ein Programm ist, was Du fernsteuern möchtest, mal die Microsoft Namespaces UIAutomation und Microsoft Active Accessibility anschauen. Das heisst wenn Dein unbekanntes fernzusteuerndes Programm "Barierrefreiheit" unterstützt, was eigentlich die meisten Standardprogramme von Haus aus tun ( auch alle .NET Programme).

    Vorteil: Du setzt auf einer Standardschnitstelle auf (statt APIs) , kannst entsprechende Controls direkt ansteuern und sogar Events abfangen
    Nachteil: UI Automation gehört bestimmt nicht zu den eingängigeren Themen

    Alles abhängig davon wie wichtig / zuverlässig/ umfangreich das sein soll, für Spielereien ist das Thema zu aufwendig.

    Aber als Alternative erwähnt werden sollte es auf jeden Fall ...
    Danke dass sich überhaupt noch jemand mit meinem Problem beschäftigt ^^

    also ich möchte mit "ALT + V" einen Tab des TabControls "anwählen" ... ich weis nicht genau an welchen handle ich das ganze schicken soll ... an den mainwindowhandle oder an den handle des TabControls direkt.

    Ich bin jetzt schon soweit, dass ich mit Send und Postmessage den Tab ausgewählt bekomme ... nur der inhalt des TabControls bleibt erhalten ... updatet sich nicht.

    Ich denke nicht dass ich über Barrierefreiheit etwas erreichen kann, da dieses Programm ein Messprogramm ist welches von einem kleinunternehmen programmiert wurde und nichtmal commandline Parameter frisst ... von daher denke ich nicht dass man in diese richtung erfolg haben könnte.

    jetzt frage ich mich wie ich das ganze lösen kann ... ich weis nicht mehr weiter.
    so ich habe mir jetzt mal einen spy++ To VB.NET converter gebastelt ^^

    weil das regt gewaltig auf wenn man testet und immer die wParam und lParam übertragen muss ...

    werd jetzt mal schauen ob es mit WM_PAINT funktioniert ;)

    wer sich das ding mal anguggen will oder interesse hat ... siehe Anhang
    Bilder
    • spyConvert.JPG

      78,6 kB, 588×533, 120 mal angesehen
    Dateien
    • SpyToVB.rar

      (12,07 kB, 113 mal heruntergeladen, zuletzt: )
    @Pascal: Dein kleines Hilfsprogramm ist schön und gut, aber wParam und lParam haben eine Bedeutung. Dort werden keine wahllosen Werte übergeben. Außerdem sind viele der übergebenen Werte Speicherzeiger, Handles oder ähnliches, also KEINE Konstanten! Wenn du die Parameter einfach aus Spy++ kopierst, funktioniert vieles maximal bis zum nächsten Neustart. Im MSDN findest du die Belegungen von wParam und lParam zu jeder Nachricht, die du an SendMessage übergeben kannst. Weiterer Vorteil: Konstanten haben Namen; dadurch wird der Code lesbarer.
    Gruß
    hal2000