Problem mit PostMessage
-
Hi, ich versuche gerade mit PostMessage ein paar Zeichen an ein inaktives Fenster zu senden ich hab schon ein fertiges Programm welches funktioniert + C# Source Code [Ich hab kp von C#].
Jetzt will ich das ganze in C++ schreiben um es an meine Bedürfnisse anpassen zu können.
Hier ist mein Code:
string name = "Unbenannt - Editor"; HWND hwnd = FindWindow (0, name.c_str() ); if(hwnd==0){ cout<<"error 1 "<< GetLastError() << endl; } hwnd = FindWindowEx ( hwnd, 0, name.c_str(), 0 ); if(hwnd==0){ cout<<"errorExe "<< GetLastError() << endl; // Gibt aus Error code 2: The system cannot find the file specified. } PostMessage(hwnd, WM_KEYDOWN, VK_SPACE, MapVirtualKey(VK_SPACE, 0)); PostMessage(hwnd, WM_KEYUP, VK_SPACE, MapVirtualKey(VK_SPACE, 0));
Hier ist der C# Code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; namespace SendKeysTutorial { class VMessages { string[] eWindowClassStructure; Int32 eClassHandle; public VMessages(string pWindowClassStructure) { eWindowClassStructure = pWindowClassStructure.Split(new string[] { "//" }, StringSplitOptions.None); eClassHandle = Win32.FindWindow(null, eWindowClassStructure[0]); if (eWindowClassStructure.Count() > 1) { for (int i = 1; i < eWindowClassStructure.Count(); i++) { eClassHandle = Win32.FindWindowEx(eClassHandle, IntPtr.Zero, eWindowClassStructure[i], null); } } //Win32.FindWindow(null, "Untitled - Notepad"); //Win32.FindWindowEx(eClassHandle, IntPtr.Zero, "Edit", null); } public Boolean windowExists() { if (eClassHandle == 0) return false; return true; } public void sendText(string pText) { char[] tmpText = pText.ToCharArray(); foreach (char c in tmpText) { sendChar(c); } } public void sendKey(System.Windows.Forms.Keys pKey) { Win32.PostMessage(eClassHandle, Win32.WM_KEYDOWN, Win32.VkKeyScan((char)pKey), 0x00140001); Win32.PostMessage(eClassHandle, Win32.WM_CHAR, 0x00000000 + (Int32)pKey, 0x00140001); Win32.PostMessage(eClassHandle, Win32.WM_KEYUP, Win32.VkKeyScan((char)pKey), 0xC0140001); } public void sendChar(char pChar) { Win32.PostMessage(eClassHandle, Win32.WM_KEYDOWN, Win32.VkKeyScan(pChar), 0x00140001); //Win32.PostMessage(eClassHandle, Win32.WM_CHAR, 0x00000000 + (Int32)pChar, 0x00140001); Win32.PostMessage(eClassHandle, Win32.WM_KEYUP, Win32.VkKeyScan(pChar), 0xC0140001); } public void Wait(float pSeconds) { System.Threading.Thread.Sleep((Int32)(pSeconds * 1000)); } } }
Hat wer eine Ahnung was ich da falsch mache?
Und ja, ich weiss mit PostMessage soll man eigentlich keine Tastatureingaben simulieren, aber da das alles an ein inaktives Fenster gesendet werden soll muss ich es ja wohl so machen. SendInput fällt hier leider weg
-
Man kann mit PostMessage keine Tasatureingaben simulieren.
Das ist Dein Problem.Verwende SendInput!
-
Martin Richter schrieb:
Man kann mit PostMessage keine Tasatureingaben simulieren.
Und wieso funktioniert das andere Programm dann?
Ich hab gerade mal kurz in das Video Tutorial reingeschaut jetzt hab ich meinen Fehler gefunden:
Ich muss nach Edit suchen _ das ist ja auch der Name der Class die den Text empfangen soll ...
hwnd = FindWindowEx ( hwnd, 0, "Edit", 0 ); if(hwnd==0){ cout<<"errorEx "<< GetLastError() << endl; }
-
PostMessage von Keyboard Nachrichten funktioniert nicht zuverlässig...
Punkt!
-
@ Martin
Das glaub ich auch das es nicht zuverlässig funktioniert (Ich hab auch deinen Beitrag dazu in deinem Blog gelesen). [In der Not frisst der Teufel fliegen oder wie heisst es?^^]
Aber gibt es dann da wirklich keine vernünftige Lösung für das Problem?Das Ziel ist halt das ein inaktives Fenster eine Tastatureingabe erhält.
Falls noch jemandem eine vernüftige Lösung dafür einfällt würde ich mich über jeden Beitrag sehr freuen.
-
Poster schrieb:
Falls noch jemandem eine vernüftige Lösung dafür einfällt würde ich mich über jeden Beitrag sehr freuen.
Inaktive Fenster könnne per Definition keine Tastatureingaben bekommen. Ein inaktives Fenster hat niemals den Fokus. Nur ein Fenster, dass den Eingabefokus hat kann auch Tastatureingaben empfangen.
Da beist sich die Katzein den Schwanz....
-
Dein C++ Programm macht halt auch was anderes als das C# Programm.
eWindowClassStructure = pWindowClassStructure.Split(new string[] { "//" }, StringSplitOptions.None); eClassHandle = Win32.FindWindow(null, eWindowClassStructure[0]); if (eWindowClassStructure.Count() > 1) { for (int i = 1; i < eWindowClassStructure.Count(); i++) { eClassHandle = Win32.FindWindowEx(eClassHandle, IntPtr.Zero, eWindowClassStructure[i], null); } }
Es gibt also nen String "pWindowClassStructure", der mit "//" getrennt einen Fensternamen gefolgt von Klassennamen enthält.
Der Code sucht bei "Foo//Bar//Baz" also erstmal ein Top-Level Window mit Namen "Foo", dann das erste Child dieses Fensters mit Klasse "Bar" und davon nochmal das erste Child mit Klasse "Baz".Dein Code dagegen...
string name = "Unbenannt - Editor"; HWND hwnd = FindWindow (0, name.c_str() ); if(hwnd==0){ cout<<"error 1 "<< GetLastError() << endl; } hwnd = FindWindowEx ( hwnd, 0, name.c_str(), 0 ); if(hwnd==0){ cout<<"errorExe "<< GetLastError() << endl; // Gibt aus Error code 2: The system cannot find the file specified. }
...sucht erstmal ein Fenster mit Namen "Unbenannt - Editor" und dann das erste Child-Window mit Klasse "Unbenannt - Editor".
Genau das dürfte der Fehler sein - die Windowclass wird wohl kaum "Unbenannt - Editor" heissen.