Laden...

Wie bekomme ich ein Handle aufs aktuell fokusierte Fenster?

Erstellt von Seikilos vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.236 Views
S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren
Wie bekomme ich ein Handle aufs aktuell fokusierte Fenster?

Ich habe eine Applikation die ab und zu Messageboxes generiert. Nun habe ich parallel einen Thread, der ein paar Werte sammeln muss.
Dafür benötige ich jedoch ein Handle auf das aktive fenster. Gibt es da so etwas wie Application.FocusedWindow? Ich kann die Logik der Applikation selber nicht modifizieren, so dass die irgendwo immer ein Flag setzt, wenn ein modales Fenster erzeugt wird.

Ich bin hier also auf die C# Funktionalität angewiesen

Life is a short

D
500 Beiträge seit 2007
vor 13 Jahren

Moin!

Laeuft die Applikation in einem anderem Prozess oder befindest Du Dich im gleichen Prozess?
Ich habe noch nicht genau verstanden, warum Du an das Fenster herankommen musst. Blockiert der modale Dialog Deinen Algorithmus oder was ist das eigentliche Problem?

Gruss,
DaMoe

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Also MessageBox ist ja Modal und ich bin gerade in einem Integrationstest bei dem das Verhalten einer Komponente getestet wird. Units wurden schon getestet, aber die Kombination von Logik, GUI(Modale MessageBox), Folgelogik sind noch nicht verifiziert.

Nun ploppt im automatisierten Test quasi eine Messagebox auf, was ja nicht so hilfreich ist.

Im Testcase mache ich vor dem Aufruf, der zu der Messagebox führt einen Timer auf, der nach einer Sekunde aufgerufen wird. Sprich

  1. timer start
  2. modale box wartet
  3. callback des timers greift.

Meine Hoffnung war nun, dass im callback des Timers über Application.OpenForms oder so auf das modale Fenster im Vordergrund komme.
Nur finde ich das modale fenster einfach nicht

Life is a short

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Seikilos,

du willst also den Handle der MessageBox haben?

Wenn alle Stricke reissen: Win32: EnumWindows.

herbivore

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Hmm ok, aber wie komme ich an die innereien eines Win32 Handles?
Ich würde sehr ungerne auf WinApi zurückgreifen müssen

Life is a short

D
500 Beiträge seit 2007
vor 13 Jahren

Hi!

Dir wird wohl nichts anderes uebrig bleiben, als auf WinAPI zurueckzugreifen.
Ich vermute mal, dass Application.OpenForms deshalb leer sein wird, da der modale Dialog nicht aus der GUI MessageLoop gestartet wurde, also indirekt irgendwo Application.Run(...) und somit in in OpenForms enthalten ist.

Vielleicht hilft Dir Folgendes weiter. Ich habe kuerzlich eine Konsolenapplikation geschrieben, die nach einem Fenster pollt und es schliesst, sobald es auftaucht.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace Utils
{
    internal class User32
    {
        // Fields
        public static readonly int ScClose = 0xf060;
        public static readonly uint WmSyscommand = 0x112;

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr windowHandle, IntPtr windowHandleChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll")]
        public static extern int SendMessage(int windowHandle, uint message, int rightParameter, int leftParameter);

        // Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.
        [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
        public static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string windowName);
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Utils
{
    internal class Program
    {
        public static void Main(string[] args)
        {
             ThreadPool.QueueUserWorkItem(state =>
            {
                for (;;)
                {
                    var windowPtr = User32.FindWindowByCaption(IntPtr.Zero, "Information");

                    if (windowPtr != IntPtr.Zero)
                    {
                        User32.SendMessage(windowPtr.ToInt32(), User32.WmSyscommand, User32.ScClose, 0);
                        Console.WriteLine("Dialog closed\n");
                    }

                    Thread.Sleep(500);
                }
            });

            Console.ReadLine();
        }
    }
}


3.511 Beiträge seit 2005
vor 13 Jahren

Na da hoff ich doch mal, dass das Ding nur für private Testzwecke genutzt wird... Wobei das so schon gegen die Lizenz verstoßen sollte.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Hallo,
danke für den Code.
Was mir nicht klar ist, weil ich mich mit WinApi nicht auskenne: Wie kann ich zum Beispiel auf Ok oder "Abort" oder "Abbrechen" bei so einer Anwendung klicken?
Über Forms hätte ich das Element ja gefunden, aber so bin ich unsicher.

Life is a short

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Na da hoff ich doch mal, dass das Ding nur für private Testzwecke genutzt wird... Wobei das so schon gegen die Lizenz verstoßen sollte.

Was meinst du?

Life is a short

3.511 Beiträge seit 2005
vor 13 Jahren

Der gepostete Code von DaMoe80 schließt automatisch den Trial-Dialog der DevExpress Komponenten. Schön ist sowas nicht.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Achso, jetzt verstehe ich.

Life is a short

S
Seikilos Themenstarter:in
753 Beiträge seit 2006
vor 13 Jahren

Hallo,
ich habe hier eine schöne Wrapper Klasse gefunden:
http://www.elitepvpers.de/forum/epvp-coders/118712-c-windows-api.html

Ich hab die User32 Funktionalität von DaMoe 80 dazu gepackt und kann nun Tastenbefehle an Fenster senden.

Danke für die Hilfe 😃

Life is a short

D
500 Beiträge seit 2007
vor 13 Jahren

Der gepostete Code von DaMoe80 schließt automatisch den Trial-Dialog der DevExpress Komponenten. Schön ist sowas nicht.

Natuerlich ist so etwas nicht schoen und gehoert sicherlich nicht zu meinem klassischen Vorgehen. Die Leistung des entsprechenden Anbieters wurde durch den Erwerb weiterer Lizenzen honoriert. Es hat lediglich den Verzug beim Erwerb der Lizenzen ueberbrueckt.