Autor Beitrag
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Fr 09.05.08 18:31 
Hallo!

Ich weiß, der Titel ist etwas komisch, handelt es sich bei SetForegroundWindow doch um eine WinAPI-Funktion. Da ich momentan kein Delphi installiert habe und mir schnell in C# etwas basteln wollte, weiß ich nicht, ob es ein C#- oder ein WinAPI- oder ein Code-Problem ist, wobei ich auf eines der letzten beiden tippe.
Es geht konkret darum, das Programm "foobar" in den Vordergrund zu holen, einen Tastendruck ("Play/Pause") zu simulieren und danach das alte Foreground-Window wiederherzustellen. Das klappt soweit auch - es ist nur so, dass ich SetForegroundWindow zweimal aufrufen muss (im Code mit ??? gekennzeichnet), damit der Rest funktioniert und ich wüsste gerne warum. Hier einmal der Code-Ausschnitt:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
                IntPtr foobarHandle = FindWindow("{97E27FAA-C0B3-4b8e-A693-ED7881E99FC1}"null); //Handle of foobar's main window
                if (foobarHandle == IntPtr.Zero) //If handle is null...
                {
                    Console.WriteLine("foobar is not running"); //... just write this onto the console
                }
                else
                {
                    if (!_SendingKey) //If there is no key being sent already... (prevents an infinite loop cause by the keybd_event which also activates the hook)
                    {
                        _SendingKey = true//... indicate that a key is being sent

                        IntPtr OldForegroundWindow = GetForegroundWindow(); //Save handle of current foreground window
/* ??? */               SetForegroundWindow(foobarHandle); //Try to bring foobar's main window into the foreground before trying it again?!
                        Thread.Sleep(500); //Sleep for some time to make sure foobar's main window is in the foreground so that it can accept the key sent
                        if (!SetForegroundWindow(foobarHandle)) //Make foobar's main window the foreground window so that it can accept the key sent
                            Console.WriteLine("Warning: foobar's main window could not be brought into the foreground, keys sent may not have any effect");

                        Thread.Sleep(500); //Sleep for some time to make sure foobar's main window is in the foreground so that it can accept the key sent
                        keybd_event((byte)Key, 000); //Send the key
                        Thread.Sleep(500); //Sleep for some time to make sure the key reaches foobar's main window while it is in the foreground
                        Console.WriteLine("Key \"" + Key + "\" sent to foobar's main window"); //Write key sent to console

                        if (!SetForegroundWindow(OldForegroundWindow)) //Restore old foreground window
                            Console.WriteLine("Warning: The old foreground (" + OldForegroundWindow.ToString() + ") window could not be restored");

                        _SendingKey = false//Key sending finished => indicate that another key can be processed
                    }
                }


Get- und SetForegroundWindow sind über DllImport eingebunden und funktionieren wie gesagt auch. Falls ihr euch über die drei Sleeps und deren wundert: wenn ich sie entferne oder deutlich kürzer mache funktioniert das Senden des Tastendrucks ebenfalls nicht. Habe ich vielleicht einen konzeptbedingten Fehler im Code?

AXMD
AXMD Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Mo 19.05.08 01:55 
Hallo!

Falls jemand nach einer Lösung sucht: nach Zeile 27 fehlte einfach ein else return; ;)

AXMD