Laden...

[gelöst] XNA Fenster in den Vordergrund bringen

Erstellt von C#ler vor 12 Jahren Letzter Beitrag vor 12 Jahren 3.671 Views
C
C#ler Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren
[gelöst] XNA Fenster in den Vordergrund bringen

Hallo,

ich habe eine Anwendung mit mehreren XNA-Fenstern, wobei das eine das Spiel und das andere ein Ladebildschirm ist. Wenn der Benutzer die Anwendung startet, läuft das Spiel und ruft während dem Laden (per Threading) den Ladebildschirm auf. Wenn das Spiel dann ganz geladen ist, muss der Benutzer auf einen Button klicken, um das Spiel zu starten. Dann beendet sich der Thread und das eigentliche Spiel läuft los. Mein Problem ist jetzt: Wenn ich den Thread mit dem Ladebildschirm beende, schließt sich das Fenster. Das andere Fenster bleibt aber im Hintergrund.
Wie kann ich das Fenster wieder in den Vordergrund bringen?
Mein Ansatz (der funktioniert, aber sehr langsam umschaltet):


            while(!LoadingScreen.Program.IsAbleToFinish) { } //Warten auf Button
            Program.T.Abort(); //Thread beenden
            _graphics.PreferredBackBufferHeight = Height; //const int die vorher festgelegt wird
            _graphics.PreferredBackBufferWidth = Width; //const int
            _graphics.ApplyChanges(); //Fenster bleibt im Hintergrund
            _graphics.ToggleFullScreen(); //Vollbild auf & wieder zu machen
            _graphics.ToggleFullScreen(); //Dauert sehr lange

Lässt sich damit was machen (wenn ja wie?) oder ist mein Ansatz vollkommen daneben?

c#ler

In theory, there is no difference between theory and practice. But, in practice, there is.

The nice thing about the Java API is that if you don't like it, just wait two minutes — it will change. Doug Lyon

P
3 Beiträge seit 2012
vor 12 Jahren

wieso benutzt du 2 fenster? lass den lade bildschirm doch im Hauptfenster anzeigen
du könntest zumbeispiel in der Update und Draw methode nen switch haben und sobald du auf den button drückst switch er halt um ... so in etwa kannst du dann auch verschiedene zustände programmieren z.B eine Pause, oder Menü ect

D
216 Beiträge seit 2009
vor 12 Jahren

Erstmal SetForegroundWindow importieren.

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

Das Handle des Fensters bokommst du in XNA mit this.Window.Handle, also an der Stelle an der du das Fenster in den Vordergrund holen willst:

SetForegroundWindow(this.Window.Handle);

Darth Maim

C
C#ler Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren

Hallo,

erstmal danke für eure Antworten.

Ich habe Prooo's Methode benutzt, weil mir die Lösung mit zwei Fenstern auch etwas komisch vorkam.
Im Hauptfenster erhalte ich aber einen Fehler bei folgendem Code:


//Main.cs
protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            _spriteBatch.Begin();

            if (Loading)
            {
                Progress.Draw(_spriteBatch); //Ladebalken
                StartGame.Draw(_spriteBatch); //Button
            }

            _spriteBatch.End(); //ObjectDisposedException wurde nicht behandelt.
                                         //Auf das verworfene Objekt kann nicht zugegriffen werden.
                                         //Objektname: "Texture2D".
            base.Draw(gameTime);
        }

Sowohl bei Progress als auch StartGame ist bei allen Texturen
FillTexture->Nicht öffentliche Member->base->base (Microsoft.Xna.Framework.Graphics.GraphicsResource)->isDisposed=false.

c#ler

In theory, there is no difference between theory and practice. But, in practice, there is.

The nice thing about the Java API is that if you don't like it, just wait two minutes — it will change. Doug Lyon

C
180 Beiträge seit 2011
vor 12 Jahren

kommt die exception auch wenn der if fall nicht eintrifft?
und was hast du mit deinem spriteBatch gemacht? also standart mäßig is der ja eigentlich ohne den unterstrich, hast du ihn umbenannt?

C
C#ler Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren

Hallo,


if(Loading = false)
//...

geht problemblos.

Das _spriteBatch ist das ganz normale, nur wegen Namenskonventionen von manchen Add-Ins habe ich es umbenannt. Die Initialisierung:


            _spriteBatch = new SpriteBatch(GraphicsDevice);

c#ler

In theory, there is no difference between theory and practice. But, in practice, there is.

The nice thing about the Java API is that if you don't like it, just wait two minutes — it will change. Doug Lyon

C
180 Beiträge seit 2011
vor 12 Jahren

also wenns ohne dem klappt dann muss es ja an Draw methoden liegen die du aufrufst
kommentiere mal erst das eine aus und dann das andere ... ma gucken obs an beiden liegt oder nur an einem

C
C#ler Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren

Bei beiden kommt die Exception.
Hier sind die Draw-Methoden (haben bei der 2-Fenster-Lösung so funktioniert!):


//GameGUI.Button
//Selbst geschrieben
public void Draw(SpriteBatch spriteBatch)
{
            if (!Visible) return;
            spriteBatch.Draw(OuterTexture, PBorderOuterRect, Color.White); //Äußerer Rahmen
            spriteBatch.Draw(InnerTexture, PBorderInnerRect, Color.White); // Innerer Rahmen
            spriteBatch.Draw(BackgroundTexture, PBackgroundRect, Color.White); // Hintergrund
            spriteBatch.DrawString(Font, PText,
                                   new Vector2(PBorderOuterRect.Center.X - Font.MeasureString(PText).X / 2,
                                               PBorderOuterRect.Center.Y - Font.MeasureString(PText).Y / 2), TextColor); //Text
}
//GameGUI.ProgressBar
//Quelle: http://lukerymarz.com/alearningexperience/2009/04/simple-xna-progress-bar.html
public void Draw(SpriteBatch spriteBatch)
{
            spriteBatch.Draw(OuterTexture, MBorderOuterRect, Color.White); //Äußerer Rahmen
            spriteBatch.Draw(InnerTexture, MBorderInnerRect, Color.White); // Innerer Rahmen
            spriteBatch.Draw(BackgroundTexture, MBackgroundRect, Color.White); // Hintergrund
            spriteBatch.Draw(FillTexture, MFillRect, Color.White); // Füllung
}

Edit: Kommentare, Quelle

In theory, there is no difference between theory and practice. But, in practice, there is.

The nice thing about the Java API is that if you don't like it, just wait two minutes — it will change. Doug Lyon

C
180 Beiträge seit 2011
vor 12 Jahren

hmm ... naja sieht eigentlich so erstma richtig aus ... zeig ma deine variablen deklarationen

C
C#ler Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren

Meinst du die Texturen?


        protected Texture2D OuterTexture,
                            InnerTexture,
                            BackgroundTexture;
//Für alle Farb-Änderungen:
        public Color BackgroundColor
        {
            get { return PBackgroundColor; }
            set
            {
                PBackgroundColor = value;
                BackgroundTexture.Dispose();
                BackgroundTexture = new Texture2D(Game.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
                BackgroundTexture.SetData(new[] { PBackgroundColor });
            }
        }

In theory, there is no difference between theory and practice. But, in practice, there is.

The nice thing about the Java API is that if you don't like it, just wait two minutes — it will change. Doug Lyon

C
C#ler Themenstarter:in
48 Beiträge seit 2011
vor 12 Jahren

Ich habe den Fehler gefunden.
Trotzdem Danke für eure Hilfe.

Ich habe die GUI-Elemente im Konstruktor erstellt, aber this.GraphicsDevice wird (anscheinend) erst danach initialisiert, also waren die Textur-Konstruktoren nicht so wie sie sein sollten.


BackgroundTexture = new Texture2D(Game.GraphicsDevice // <- nicht initialisiert
, 1, 1, false, SurfaceFormat.Color);

Ich habe jetzt die Konstruktoren für Progress und StartGame in

protected override void Initialize()

verschoben, damit funktioniert es.
c#ler

In theory, there is no difference between theory and practice. But, in practice, there is.

The nice thing about the Java API is that if you don't like it, just wait two minutes — it will change. Doug Lyon