Feedback

C# - Fenster animiert öffnen und schließen

Veröffentlicht von am 11/30/2008
(3 Bewertungen)
Für Fenster die animiert geöffnet werden sollen (z.B. mit einen Einblendeffekt animiert ) stellt die Windows Api eine recht nette Funktion namens AnimateWindow zur Verfügung. Es kann zwischen verschiedenen Effekten gewählt werden:
- AW_BLEND öffnet ein Fenster mit Einblendeffekt
- AW_CENTER rollt das Fenster von der Mitte aus ein
- AW_HOR_xxx und AW_VER_xx rollt die Fenster seitlich oder vertikal ein.

using System.Runtime.InteropServices

public partial class Form1 : Form
{
  public Form1()
  {
      InitializeComponent();
      Button Button1 = new Button();
      Controls.Add(Button1);
      Button1.Location = new Point((Width - Button1.Width) / 2, Height - 80);
      Button1.Text = "Schließen";
      Button1.Click += new EventHandler(Button1_Click);
  }

  public new void Show()
  {
     AnimateWindow(this.Handle, 500, AW_BLEND | AW_ACTIVATE );
      // Wichtig, sonst sieht man nur ein leeres Fenster...
      Visible = true;
  }

  public new void Close()
  {
      if (IsDisposed == false)
      {
        AnimateWindow(this.Handle, 400, AW_HIDE | AW_BLEND);
        base.Close();
      }
  }

  void Button1_Click(object sender, EventArgs e)
  {
      Close();
  }


  [STAThread]
  static void Main()
  {
    Form1 f = new Form1();
    // Wichtig: Application.Run benutzt eine anderen Mechanismus, daher muss es schon vorher angezeigt werden
    f.Show();
    Application.Run(f);
  }

  #region Win32
  const int AW_HIDE = 0X10000;
  const int AW_ACTIVATE = 0X20000;
  const int AW_SLIDE = 0X40000;
  const int AW_BLEND = 0X80000;
  const int AW_HOR_POSITIVE = 0X1;
  const int AW_HOR_NEGATIVE = 0X2;
  const int AW_VER_POSITIVE = 0x4;
  const int AW_VER_NEGATIVE = 0x8;
  const int AW_CENTER = 0x10;

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern int AnimateWindow(IntPtr hwand, int dwTime, int dwFlags);
  #endregion
}

16 Kommentare zum Snippet

Günther Foidl schrieb am 12/1/2008:
if (IsDisposed == false)

sollte vermieden werden da IsDisposed ein bool ist und somit nur true/false sein kann. So eine Art der Prüfung ist Schwachsinn.
Korrekt:

if (!IsDisposed)

also mit der Negation!

Sonst ein super Snippet.
knoyxz schrieb am 12/3/2008:
Hallo Stefan, interessanter Beitrag von dir. :-)

Alternativ könnte zum Einblenden folgender Code verwendet werden:
//using System.Threading;
private void Form1_Load(object sender, EventArgs e)
{
this.Opacity = 0;
Thread thread = new Thread(einblenden);
thread.Start();
}

private void einblenden() {
MethodInvoker ansichtAktualisieren = delegate{
this.Opacity += 0.05;
};
Invoke(ansichtAktualisieren);
Thread.Sleep(50);
if (this.Opacity < 1.0) einblenden();
}


@Günther
Die Schreibweise von Stefan ist kein Schwachsinn!
Du verwendest lediglich die Kurzform...

Schönen Gruß
knoxyz
Günther Foidl schrieb am 12/4/2008:
Die Schreibweise ist unsinnig. Wenn man verstanden hat dass Boolsche-Variablen nur 0/1 (oder false/true) sein können und weiß dass ein If nur auf true/false prüft dann versteht man warum, sonst eben nicht ;)
Black Hawk schrieb am 12/5/2008:
und? sein code läuft und das ! prüft auch bloss auf false, also - er hats umständlicher gemacht aber auch lesbarer, gerade für anfänger wichtig.
Rainer Hilmer schrieb am 12/5/2008:
Einfacher zu lesen ist es für Anfänger, da gebe ich dir Recht - wenn es da nur nicht Design Guidelines gäbe. Mach dich mal auf MSDN schlau.
Günther Foidl schrieb am 12/5/2008:
Die korrekte Schreibweise ist außerdem um fast das doppelte schneller.
Wir können ja 2 Gruppen machen: Anfänger und Programmierer. Es kann sich dann jeder selbst aussuchen wo er zugehörig ist. Ich nehme die 2. Gruppe ;)
Günther Foidl schrieb am 12/5/2008:
[qutoe]das ! prüft auch bloss auf false[/quote]Also mit den Grundlagen fehlst weit. ! negiert und dabei wird nichts geprüft.
knoyxz schrieb am 12/5/2008:
@Günther

Wie gesagt, ist die Negation lediglich eine Kurzform, nichts weiter!
Aus Gründen der Lesbarkeit nutze und empfehle ich es nicht, da es zu schnell übersehen werden kann.

Es es ist falsch, dass:
* eine Negation nicht geprüft werden muss (rein logisch schon...)
* die Schreibweise mit Negation eine Performancevorteil haben soll (soeben hiermit getestet)


DateTime startzeit = System.DateTime.Now;
int i = 1;
bool biba = false;

while (biba == false) {
//while (!biba) {

i++;
if (i < 0) biba = true;
}


String dauer = new DateTime(System.DateTime.Now.Ticks - startzeit.Ticks).ToString("mm 'Minuten und' ss 'Sekunden'");
MessageBox.Show("Dauer: " + dauer);


Gruß
knoxyz
Günther Foidl schrieb am 12/5/2008:
[quote]Wie gesagt, ist die Negation lediglich eine Kurzform, nichts weiter![/quote]
Die Negation ist eine Operation und keine Kurzform.

[quote]eine Negation nicht geprüft werden muss (rein logisch schon...)[/quote]
Da eine Negation eine Operation ist liefert die ein Ergebnis und dieses Ergebnis wird geprüft und nicht die Negation - das hab ich nie anders behauptet - du musst schon lesen was da steht (und nicht das was nicht da ist).

[quote]die Schreibweise mit Negation eine Performancevorteil haben soll (soeben hiermit getestet)[/quote]
Der Performance-Vorteil ist tatsächlich nicht vorhanden, da der Compiler den Code optimiert und if (!b) schreibt (siehe IL-Code, oder jede beliebige ander Programmsprache deren Compiler was taugt).
Anmerkung zu deinem Test: Besser wäre schon ein Test bei dem sich der zu prüfende Ausdruck in jedem Schleifendurchlauf ändert, somit hätte die CLR weniger Chance etwas zu optimieren.

Wie gesagt: Es gibt richtige Programmierer die if (!b) schreiben da dies der Boolschen Logik entspricht.
Rainer Hilmer schrieb am 12/6/2008:
@Günther: Lassen wir es. Manche Menschen sind eben beratungsresistent. :-/
Es gibt sinnvollere Dinge, mit denen wir unsere Zeit verbringen können.
knoyxz schrieb am 12/7/2008:
Das
Nagationszeichen ist ein Operator, keine Operation
.

Macht besser eine Gruppe, "Wir sind Schlaumeier" auf.
Und beratungsresistent sind wir ganz sicher nicht!
Wir wollen nur nicht alles blind glauben, was man uns versucht unterzujubeln.
Günther Foidl schrieb am 12/7/2008:
[quote]beratungsresistent[/quote]Das bist du schon. Ich erinner dich an eines deiner Snippets wo du mir auch Fehler unterstellt hast und nachdem du es geprüft hast merken musstest dass ich (oder ein "Programmierer") doch Recht hatte.

Es versucht niemand etwas unterzujubeln, sonder lediglich auf Falsches hinzuweisen und das Korrekte darzustellen. Aber richtig/falsch ist für dich ja nicht definierbar.

Es bringt nichts da weiter zu diskutieren.
Ende.
Dirk Klimke schrieb am 12/7/2008:
Hallo,

puh... was für eine seltsame Diskussion. Ich habe recht.. nein ich, nein ich. Erinnert ein wenig an Kindergarten. ;-) Ich persönlich preferiere auch die Schreibweise (!b) da ich sie leserlicher finde und im Kontext einer CLR Sprache logisch ist. Aber was macht ein Entwickler der von C kommt? Viele Entwickler die von C/C++ auf eine .NET Sprache wechseln schreiben so etwas wie (b == false). Und dafür haben sie einen Grund. Ok, wenn sie gut wären wüssten sie das sie es nicht bräuchten. Aber es gibt in der Windows Programmierung unter C++ zwei Wege einen Bool zu definieren. bool b = false; und BOOL b = FALSE; (Auch denkbar-> BOOL b = false oder bool b = FALSE). In der ersten Variante ist (!b)ok in der zweiten nicht zwingend.
Die erste Variante kommt vom OS und ist wirklich nur ein Bit. Die zweite kommt aus der WinDef.h und ist wie folgt definiert.
typedef int BOOL;
In der afx.h werden die folgenden Werte definiert.
#define FALSE 0
#define TRUE 1

Das bedeutet das BOOL ein 32Bit Integer ist. Warum man das so gemacht hat?
Ein 32Bit OS kann einen 32Bit Integer schneller lesen als ein(en) Bit.

Ich definiere BOOL b;
Wenn ich nun frage if(!b) so ist das Ergebnis true wenn
a) b == 0 ist ODER
b) b < 0 ist

Genauso verhält es sich umgekehrt. Das Ergebnis von if(b) ist true wenn b > 0 ist.
Bei einem uninitialisierten BOOL könte 2.147.483.647 stehen, somit wäre das Ergebnis der Abfrage true obwohl ich 1 meinte. Aus diesem Grund schreibt man if(b == TRUE).

Das ist nun eine eher historische Anmerkung zu dieser Diskussion. Aber wichtig ist das man weiß worüber man spricht. Benutzt in CLR Sprachen (!b) und alles wird gut. Denn so geile Dinge wie typedef gibt es in .NET leider nicht.
handycommander schrieb am 12/7/2008:
Ich denke mal, hier geht es um das Snippet von Stefan und nicht um eure Diskussion, wie man jetzt auf true/false prüft...

MfG
Andromeda schrieb am 2/24/2013:
Tobi82 schrieb am 4/11/2017:
Man schreibt doch auch nicht:
if(IsDisposed != true)
obwohl es funktioniert hehe also da muss ich Günther recht geben.
 

Logge dich ein, um hier zu kommentieren!