Donnerstag, 31. Juli 2008

Passwort Verwalter Dot Net - Version 1.2

Der Passwort Verwalter Dot Net hat ein erneutes Update erhalten: Version 1.2 bietet folgende neue Features:

  • Bugfix: Aktivierung/Deaktivierung von Menüpunkten im Hauptmenü
  • Bugfix: Programminterne Hilfe: Sprung zum jeweiligen Kapitel
  • Bugfix: Suche: Markierung des Treffer-Feldes
  • Bugfix: Verzögerung beim (1.) Anzeigen des Suchen-Dialogs
  • Backupmanager hinzugefügt
  • Datenfelder können nachträglich gelöscht werden (sofern keine Daten mehr in diesem Datenfeld vorhanden sind)
  • Einträge können in andere Kategorien verschoben werden
  • Feedbackdialog hinzugefügt
  • Logindialog überarbeitet (Untersützung für Schlüsseldateien)
  • Hauptfenster kann in der Größe (begrenzt) verändert werden
  • Neues Tool "Notizblock" verfügbar
  • Schlüsseldateien (Keyfiles) verfügbar (incl. 4 Sichermeitsmodi)
  • Standard-Zufallspasswort kann konfiguriert werden
  • Verwendete Datei kann per Drag & Drop in Start- sowie Loginform geändert werden
  • Verzeichnis der aktuellen Datei kann im Explorer angezeigt werden (Haupfenster-Menüeintrag)

Projekt-Homepage: www.pwvdotnet.org

Direktdownload: pwvdotnet_v1200_setup.exe oder pwvdotnet_v1200.zip (portable)

Mittwoch, 30. Juli 2008

Dot Net (C#): Screenshot von einem Control erzeugen

Folgende zwei Methoden sind nötig, um einen Screenshot von einem Control zu erzeugen und diesen in eine Datei zu speichern:

   1:  public static Bitmap takeScreenshot(Control pControl)
   2:  {
   3:      Bitmap bmp = new Bitmap(pControl.Width, pControl.Height);
   4:      pControl.DrawToBitmap(bmp, Rectangle.FromLTRB(0, 0, pControl.Width, pControl.Height));
   5:      return bmp;
   6:  }
   7:   
   8:  public static Boolean saveScreenshotToFile(Control pControl, String pFilename)
   9:  {
  10:      try
  11:      {
  12:          takeScreenshot(pControl).Save(pFilename);
  13:          return true;
  14:      }
  15:      catch (Exception)
  16:      {
  17:          return false;
  18:      }
  19:  }

Die erste Methode nimmt einen Screenshot auf und speichert diesen in einem Bitmap-Objekt. Die zweite Methode kann genutzt werden, um den Screenshot direkt in eine Datei zu speichern.

Dienstag, 17. Juni 2008

Dot Net (C#): Drag & Drop

Drop von Dateien / Ordnern:

1. Vorbereitung:

"AllowDrop"-Property setzen und 2 Events anmelden:

   1:  public MainForm()
   2:  {
   3:      InitializeComponent();
   4:      this.textboxDir.AllowDrop = true;
   5:      this.textboxDir.DragOver += new DragEventHandler(textboxDir_DragOver);
   6:      this.textboxDir.DragDrop += new DragEventHandler(textboxDir_DragDrop);
   7:  }


2. Drag Over-Event:

DataFormat überprüfen und DragDropEffects setzen:

   1:  void textboxDir_DragOver(object sender, DragEventArgs e)
   2:  {
   3:      if (e.Data.GetDataPresent(DataFormats.FileDrop))
   4:      {
   5:          e.Effect = DragDropEffects.Move;
   6:      }
   7:  }


3. Drag-Drop-Event:

Drop auswerten:

   1:  void textboxDir_DragDrop(object sender, DragEventArgs e)
   2:  {
   3:      if (e.Effect == DragDropEffects.Move) // if move
   4:      {
   5:          if (e.Data.GetDataPresent(DataFormats.FileDrop)) // if file drop
   6:          {
   7:              string[] dirNames = (string[])e.Data.GetData(DataFormats.FileDrop);
   8:              if (dirNames.Length.Equals(1)) // wenn genau eine datei
   9:              {
  10:                  if (MSUtils.FileUtil.dirExists(dirNames[0]))
  11:                  {
  12:                      this.textboxDir.Text = dirNames[0];
  13:                  }
  14:              }
  15:          }
  16:      }
  17:  }

Montag, 16. Juni 2008

Opera 9.5 und öffentlicher ACID3-Build

Der Opera-Browser ist am 12.06.2008 in der Version 9.5 erschienen. Diese Version bringt viele neue Features mit sich:

  • Extended-Validation-SSL-Zertifikate
  • Adressleiste mit besseren Vorschlägen für bereits besuchte Seiten
  • bessere Unterstützung von Web-Standards (JavaScript, CSS, SVG, MathML)
  • Opera-Link (Synchronisation von Bookmarks und Co.)
  • neues Skin (altes Skin aber noch verfügbar)
  • schnellerer Seitenaufbau
  • weiches Scrollen
  • neue Entwicklerwerkzeuge
Opera 9.5 kann in mehr als 25 Sprachen hier heruntergeladen werden: http://www.opera.com/download/



Im ACID3-Test schafft diese Version ca. 85 Punkte. Ein öffentlicher Build, der 100 Punkte im ACID3-Test schafft, ist hier zu finden: http://labs.opera.com/news/2008/03/28/

Ich habe mich an einen kleinen Browservergleich gewagt, was die (Lade-)Geschwindigkeit angeht. Dabei habe ich Internet Explorer in den Versionen 6 sowie 7, Firefox in den Versionen 2.0 und 3.0 (RC3) sowie Opera in den Versionen 9.27 und 9.5 verwendet.

Das Ergebnis:




Dabei lädt Opera in der Version 9.5 die 8 ausgewählten Webseiten in 75 Sekunden (gegenüber 101s IE7 und 93s Firefox 3). Der Test berücksichtigt das Neuladen einer Webseite sowie das Laden derselben aus dem Cache. Dabei war Opera 9.5 in keinem einzigen Fall der langsamste Browser.

Dienstag, 8. April 2008

Dot Net (C#): Invoke()-Methode für MultiThread-Applikationen mit WindowsForms

Um ein Control auf einer WindowsForms von einem anderen Thread aus zu verändern, muss die Invoke()-Methode der Form oder des Controls verwendet werden. Ein Control darf nur von dem Thread geändert werden, von dem es erzeugt wurde!

Folgendes Minimal-Beispiel (unvollständig) zeigt einen Anwendungsfall, in dem ein Thread seinen Status an eine Form berichtet:

Die Klasse MathClass erzeugt Thread-Objekte, deren Methode CalcBackground() in einem Thread ausgefürt wird.Aus dieser Methode heraus soll die GUI über den aktuellen Thread-Status informiert werden:

   1:   
   2:      public class MathClass
   3:      {
   4:   
   5:          private MainForm myForm;
   6:          private int iNumber;
   7:   
   8:          public Thread Initialize(MainForm myform, int number)
   9:          {
  10:              this.myForm = myform;
  11:              this.iNumber = number;
  12:              return new Thread(new ThreadStart(this.CalcBackground));
  13:          }
  14:   
  15:          delegate void UpdateUI(int number, int state);
  16:          delegate void Finish(int number);
  17:   
  18:          public void CalcBackground()
  19:          {
  20:              UpdateUI updateUI = new UpdateUI(this.myForm.updateUIProc);
  21:              Finish finish = new Finish(this.myForm.FinishThread);
  22:   
  23:              try
  24:              {
  25:                  // do something
  26:                  // ...
  27:                  // report status to form:
  28:                  object[] param = new object[2] { this.iNumber, i };
  29:                  myForm.Invoke(updateUI, param); // call myForm.updateUIProc(iNumber, i)
  30:              }
  31:              catch (ThreadAbortException)
  32:              {
  33:                  // clean up
  34:              }
  35:              catch (Exception)
  36:              {
  37:                  // catch any other exception
  38:              }
  39:              finally
  40:              {
  41:                  try
  42:                  {
  43:                      // call myForm.FinishThread(iNumber)
  44:                      myForm.Invoke(finish, new object[] { this.iNumber }); 
  45:                  }
  46:                  catch (ObjectDisposedException e)
  47:                  {
  48:                  }
  49:                  catch (Exception ee)
  50:                  {
  51:                  }
  52:              }
  53:          }
  54:   
  55:      }

Die Mainform erzeugt in der Methode startThreads() zwei neue Threads. Die Methoden updateUIProc() sowie FinishThread() werden per Invoke()-Methode von Thread aus gestartet und laufen selbst im Thread der Mainform:
   1:      public partial class MainForm : Form
   2:      {
   3:   
   4:          public MainForm()
   5:          {
   6:              InitializeComponent();
   7:          }
   8:   
   9:          private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  10:          {
  11:              // kill threads before form closes
  12:              if (anyThreadAlive)
  13:              {
  14:                  killThreads();
  15:              }
  16:          }
  17:   
  18:          public void updateUIProc(int number, int val)
  19:          {
  20:              this.textBox1.AppendText(
  21:                  string.Format("thread {0} has done {1} % of its job", number, val));
  22:          }
  23:   
  24:          public void FinishThread(int number)
  25:          {
  26:              this.textBox1.AppendText(
  27:                  string.Format("thread {0} has finished", number));
  28:          }
  29:   
  30:          private void startThreads()
  31:          {
  32:              Thread th1 = new MathClass().Initialize(this, 0);
  33:              Thread th2 = new MathClass().Initialize(this, 1);
  34:              th1.Start();
  35:              th2.Start();
  36:          }
  37:      }

Es ist nicht erlaubt, das Control Mainform.textBox1 direkt aus dem Thread zu verändern.Ein Control darf nur von dem Thread verändert werden, von dem es erstellt wurde.Um trotzdem ein Control aus einem Thread heraus zu verändern, benutzt man die Methode Invoke() und übergibt dieser ein delegate (Funktionszeiger) sowie ein Parameterarray. Die eigentliche Methode (z.B. updateUIProc() oder FinishThread()) läuft anschließend (in diesem Fall) im Thread der MainForm. Dies hat ebenfalls zur Folge, dass keine der beiden Funktionen parallel mehrmals ausgeführt werden kann.

Donnerstag, 3. April 2008

Dot Net (C#): SearchOption.AllDirectories für GetDirectories()

Die Methode GetDirectories() der Klasse DirectoryInfo liefert alle zu einem Suchpattern passenden Verzeichnisse. Dabei liefert der Aufruf

dir.GetDirectories("Release*")

beispielsweise alle Verzeichnisse, die mit "Release" beginnen. Um dies für alle Unterverzeichnisse nicht rekursiv programmieren zu müssen, gibt es die Möglichkeit, die GetDirectoties()-Methode mit einem weiteren Parameter zu füttern:

dir.GetDirectories("Release*", SearchOption.AllDirectories)

Bei diesem Aufruf werden automatisch alle Unterverzeichnisse abgesucht. Dies erspart einem das rekursive Aufrufen von Methoden, was den Code wesentlich kürzer macht.

Genauso verhält es sich mit der Methode GetFiles().

Visual Studio: Methoden nachträglich generieren

Seit dem Visual Studio 2008 kann man Methoden nachträglich automatisch generieren lassen. Nehmen wir an, wir wollen (später) die folgende Methode generieren:

processDir(listFiles, this._strPath, pattern);

Nun schreibt man diese Methode einfach als Aufruf hin, obwohl diese noch nicht existiert. Ein anschließender Rechtsklick auf den Methodennamen sowie ein Klick auf den Eintrag "Generate Method Stub" erzeugt die angegebene Methode incl. der vorgegebenen Signatur in der aktuellen Klasse.


Anklicken für Vollansicht

Es wird folgende Methode generiert:
private void processDir(List<string> listFiles, string p, string pattern)
{
throw new NotImplementedException();
}

Die erzeugte Methode ist private, evtl. Rückgabewerte werden ebenfalls angelegt.

Dies ermöglicht einem, den Code für einen Anwendungsfall vollständig zu schreiben, ohne zwischendurch wegen anderen Methoden, die man später implementieren will, unterbrochen zu werden.