Senden Tastendruck auf die Anwendung in c# (sendkeys, postmessage, sendmessage alle nicht arbeiten)
Ich versuche zu tun, eine der folgenden
1. öffnen Sie das gewünschte Programm und drücken Sie eine Taste, programmgesteuert
2. finden Sie Fenster öffnen von Programm und drücken Sie eine Taste, programmgesteuert
(entweder ist in Ordnung)
Ich habe versucht zahlreiche Implementierungen von SendKeys.SendWait(), PostMessage () und SendMessage() erfolglos. Hier sind meine code-snippets
//included all these for attempts
[DllImport("User32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
[DllImport("user32.dll")]
static extern byte VkKeyScan(char ch);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
Get Griff von Fenster, Variablen, die durch sendmessage/postmessage/sendkeys
IntPtr ptrOBS = proc.Handle;//this works properly, proc is instantiated properly
//IntPtr ptrOBS = FindWindow(null, "Open Broadcaster Software v0.472b");
SetForegroundWindow(ptrOBS);
const UInt32 WM_CHAR = 0x0102;
const uint WM_KEYDOWN = 0x100;
const int VK_R = 0x52; //taken from http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx
const int VK_S = 0x53;
SendMessage Versuch:
SendMessage(ptrOBS, WM_KEYDOWN, (IntPtr)VK_R, (IntPtr)1);//tried both WM_CHAR and WM_KEYDOWN
PostMessage versuchen:
string message = "rs";
bool sent = PostMessage(ptrOBS, WM_KEYDOWN, VkKeyScan(message[0]), 0);
SendKeys Versuch:
SendKeys.SendWait("{r}");
Versucht SetFocus auf das übergeordnete Fenster (Anwendung) und untergeordnete Fenster (Schaltfläche ausgelöst durch Tastendruck im, der versucht zu senden):
static void SetFocus(IntPtr hwndTarget, string childClassName)
{
//hwndTarget is the other app's main window
//...
IntPtr targetThreadID = GetWindowThreadProcessId(hwndTarget, IntPtr.Zero); //target thread id
IntPtr myThreadID = GetCurrentThread(); //calling thread id, our thread id
try
{
bool lRet = AttachThreadInput(myThreadID, targetThreadID, -1); //attach current thread id to target window
//if it's not already in the foreground...
lRet = BringWindowToTop(hwndTarget);
SetForegroundWindow(hwndTarget);
//if you know the child win class name do something like this (enumerate windows using Win API again)...
IntPtr hwndChild = (IntPtr)1183492;//(IntPtr)EnumAllWindows(hwndTarget, childClassName).FirstOrDefault();
if (hwndChild == IntPtr.Zero)
{
//or use keyboard etc. to focus, i.e. send keys/input...
//SendInput (...);
return;
}
//you can use also the edit control's hwnd or some child window (of target) here
SetFocus(hwndChild); //hwndTarget);
SendKeys.SendWait("{r}");
}
finally
{
SendKeys.SendWait("{r}");
bool lRet = AttachThreadInput(myThreadID, targetThreadID, 0); //detach from foreground window
SendKeys.SendWait("{r}");
}
}
Für NSGaga:
string windowName = "Open Broadcaster Software v0.472b";
IntPtr outerPtr = FindWindow(null, windowName);
IntPtr ptrOBS = (IntPtr)527814;//button that im trying to trigger keypress on
SetForegroundWindow(outerPtr);
SetForegroundWindow(ptrOBS);
SetFocus(outerPtr, "OBSWindowClass");//SetFocus(ptrOBS, "Button");
const UInt32 WM_CHAR = 0x0102;
const int VK_R = 0x52; //taken from http://msdn.microsoft.com/en-us/library/dd375731(v=vs.85).aspx
const int VK_S = 0x53;
//SetForegroundWindow(ptrOBS);
System.Threading.Thread.Sleep(3000);
SendKeys.SendWait("{r}");
SendMessage(outerPtr, WM_KEYDOWN, (IntPtr)VK_R, (IntPtr)1);
PostMessage(outerPtr, WM_KEYDOWN, VkKeyScan('r'), 0);
heh, ich hätte gestanzt die Wand, wenn das der Fall war, nicht einen Unterschied machen.
Siehe: stackoverflow.com/questions/4944621/...
InformationsquelleAutor SPillai | 2013-03-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da ist viel Versuch und Irrtum, um es zu erhalten arbeitend
Hier ist ein wenig code, den ich gepostet vor, Sie würde vielleicht einen Versuch geben (und es gibt ein paar mehr Infos angebracht)...
Pinvoke SetFocus auf ein bestimmtes Steuerelement
Versuchen Sie, konzentrieren Sie sich zunächst (mit dem Mechanismus erwähnt) - und dann mit
SendKeys
oderSendInput
.Hier finden Sie einige detaillierte code für
SendInput
...Gewusst wie: senden einer Zeichenkette an anderen Anwendung, einschließlich Microsoft Word
hast du es geschafft zu
SetFocus
auf alles, was in der Ziel-Fenster - verwenden, was ich vorgeschlagen habe (das muss befolgt werden, um die Buchstaben) - das ist der erste Schritt. Ich hatte, dass die Arbeit um ein Vielfaches. Aber einige apps sind bestimmte. Auch versuchen Sie, erheben Sie Ihre app (als admin), wenn es hilft.oder posten Sie Ihre endgültige code, den Sie gemacht haben (mit Ansatz) - werde ich kopieren und einfügen, und führen Sie hier (einstellen) und versuchen, einen Blick zu nehmen, wenn es die Zeit erlaubt
setfocus-Implementierung, die ich versuchte, war oben; wollen Sie mir die post meine win32-api-Funktion Erklärungen oder einfach nur das aufrufen der setfocus-dann sendkeys?
am besten in voller repro (nur abgeholzt, um min - z.B. versuchen, mit dem Editor (notepad oder so) - das ist am einfachsten, mit zu arbeiten (gemeinsame Probe)
InformationsquelleAutor NSGaga
Sie können nicht zuverlässig, verwenden Sie
SendMessage
undPostMessage
für die Synthese von Tastatur-Eingaben. Sie sind einfach nicht konzipiert für diese. Diese Nachrichten (WM_CHAR
,WM_KEYDOWN
usw.) sind Benachrichtigungen ausgelöst durch die untere-Ebene-Subsysteme bei der Tastatur-Eingabe wurde empfangen, verarbeitet und weitergeleitet werden an die entsprechenden Empfänger. Senden oder posten diese Nachrichten selbst ist wie Streich-Aufruf jemand.SendKeys
(wie alle anderen input-synthesizer-Methoden, einschließlich derSendInput
Funktion, die explizit dazu entwickelt wurde, zur Synthese von Tastatur-Eingabe-und in wenigstens einigen der Implementierung ist es, wasSendKeys
tatsächlich nutzt unter der Haube) funktioniert nur, wenn das Fenster, das Sie erhalten möchten, die Tastatur den Fokus hat. In Windows, nur konzentriert (aktiven) windows-empfangen von Eingabe-Ereignissen.So
SendKeys
ist wahrscheinlich der Weg zu gehen, wenn du jemals gehst, um diese zu arbeiten (entweder das, oder P/AufrufenSendInput
und alle zugehörigen Strukturen), aber Sie tun müssen, um die Achtung der Einschränkung, dass der Empfänger Fenster muss Fokus. Ansonsten, es wird nicht gehen, um alles zu erhalten.Sieht es aus wie aus deinem Beispiel-code, den Sie versuchen zu verwenden, die
SetForegroundWindow
Funktion erfüllen diese Voraussetzung. Leider sind Sie übergeben Sie einen ungültigen Wert, und nicht damit, irgendwelche Fehler überprüfen, könnte Sie warnen, diese Fehler. Speziell dieser code ist falsch:Selbst wenn ich Ihnen Vertrauen auf
ptrOBS
wird initialisiert korrekt, das macht es ein gültiges handle auf einen Prozess, das ist eine ganz andere Sache als ein gültiges handle auf einen Fenster. Abgesehen von der offensichtlichen nominalen Unterschiede, Prozesse können mehrere Fenster und nur ein einzelnes Fenster kann den Fokus haben (d.h., "im Vordergrund").Benötigen Sie den Griff, um ein bestimmtes Fenster vor dem Aufruf
SetForegroundWindow
, und da wir wissen, kann ein Prozess mehrere Fenster, kann schwierig sein. Sie benötigen einige zuverlässige Weise zu bestimmen, in welchem Fenster Sie wollen. Viele Menschen erreichen dies durch harte Codierung der name des Fensters als string, das funktioniert Super, bis die Ziel-app wird kompiliert, und die Umsetzung dieser änderungen im detail. Die einzige kompromisslose Weise, dass ich denken kann, ist der Benutzer klicken Sie auf das Ziel-Fenster und der code zum abrufen des handle des Fensters, das sich gerade unter dem Mauszeiger befindet.Und natürlich sind alle davon ausgegangen, dass Sie beobachtet habe, die Beschränkungen für die Verwendung von
SetForegroundWindow
, aufgelistet im Abschnitt "Hinweise" der verlinkte SDK-Dokumentation.Haben Sie sichergestellt, dass
FindWindow
tatsächlich gibt ein handle zurück? Der richtige Griff? Spy++, verwenden um dies zu überprüfen, durch Vergleich mit der tatsächlichen handle des Fensters, das Sie interessiert.es tut Rückkehr der eigentlichen parent-Fenster der Anwendung. Ich habe auch versucht das hartcodieren der Typ IntPtr hex=>Dezimalwert für die Kind-Fenster-Gehäuse die Aktion, die ich ausführen möchten mit Tastendruck (die Taste, hotkey drückt). mit entweder/sowohl windows hat nicht funktioniert. Ich habe versucht, die Umsetzung SetFocus (wird update-OP mit meinem Versuch)
InformationsquelleAutor Cody Gray