Entwickler-Ecke

Sonstiges (.NET) - SetForegroundWindow-Problem


AXMD - Fr 09.05.08 18:31
Titel: SetForegroundWindow-Problem
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:


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 - Mo 19.05.08 01:55

Hallo!

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

AXMD