jenswinter.com
Software Development 24/7

Design-Pattern-Manie

November 26, 2005 21:17 by Jens
Scott Allen ist besessen von Design Patterns. Jedenfalls ist das Schreiben von solchen Stories ein sicheres Zeichen dafür. Laughing

How to: Passwort im PropertyGrid

November 25, 2005 21:16 by Jens
Wie kann das PropertyGrid verwendet werden um den Nutzer Passwörter eingeben zu lassen?
  • Die Passwort-Eigenschaft darf nicht im Klartext im Grid zu sehen sein. Stattdessen soll für jedes Zeichen ein Asterisk angezeigt werden.
  • Die korrekte Eingabe des Passwortes sollte über eine zweite Abfrage abgesichert werden.
Als Beispiel benutze ich die Klasse LoginInfo:

 

    public class LoginInfo

    {

        private string m_UserName;

        private string m_Password;

 

        [Category("Credentials")]

        public string UserName

        {

            get { return m_UserName; }

            set { m_UserName = value; }

        }

 

        [Category("Credentials")]

        public string Password

        {

            get { return m_Password; }

            set { m_Password = value; }

        }

    }

 

Eine Instanz soll vom Nutzer im PropertyGrid editiert werden können:

Man benötigt eine Klassenbibliothek, die das Formular für die Passworteingabe, eine von UITypeEditor abgeleitete Klasse und eine von StringConverter abgeleitete Klasse. Das Formular ist schnell zusammengeklickt. Nicht vergessen, die Eigenschaft PasswordChar der Textboxen auf "*" zu setzen. Das Formular erweitere ich noch um die Eigenschaft Passwor:

 

        public string Password

        {

            get { return PasswordTextBox.Text; }

        }

 

Und im Closing-Ereignis wird noch geprüft, ob die Inhalte der TextBoxen beim Klick auf den Ok-Schalter identisch sind:

 

        private void PasswordEditForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)

        {

            if (PasswordTextBox.Text != ConfirmPasswordTextBox.Text)

            {

                MessageBox.Show("Password values entered do not match.", "MyApp", MessageBoxButtons.OK, MessageBoxIcon.Error);

                e.Cancel = true;

            }

        }

 

Der Eingabedialog soll erscheinen, wenn die Eigenschaft Password im PropertyGrid zum Bearbeiten ausgewählt wird. Dafür muss eine Klasse vom Typ UITypeEditor abegeleitet werden:

 

    public class PasswordEditor : UITypeEditor

    {

        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)

        {

            return UITypeEditorEditStyle.Modal;

        }

 

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)

        {

            PasswordEditForm form = new PasswordEditForm();

            if (form.ShowDialog() == DialogResult.OK)

            {

                return form.Password;

            }

            else

            {

                return value;

            }

        }

    }

 

Die überschriebene Methode GetEditStyle liefert UITypeEditorEditStyle.Modal zurück, damit der kleine Schalter mit den drei Punkten im Grid erscheint. Das Überschreiben der Methode EditValue sorgt dafür, dass das Eingabeformular aufgerufen wird und dass der eingegebene Wert zurückgeliefert wird.

Zuletzt muss noch dafür gesorgt werden, dass im PropertyGrid immer nur Sternchen, und nicht der tatsächliche Inhalt der Passwort-Eigenschaft sichtbar sind. Dafür muss von der Klasse StringConverter abgeleitet werden:

 

    public class PasswordStringConverter : StringConverter

    {

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)

        {

            return false;

        }

 

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)

        {

            return String.Empty.PadLeft(((string)value).Length, '*');

        }

    }

 

CanConvertFrom liefert false zurück. Damit wird verhindert, dass der Nutzer bei der Eigenschaft Password einen Wert direkt eingeben kann. Er wird somit gezwungen, auf den Schalter zu drücken um die Eigenschaft zu setzen. ConvertTo sorgt dafür, dass nur noch Sternchen für das Grid zurückgeliefert werden.

Damit das Ganze auch wirkt, muss die LoginInfo-Klasse noch angepasst werden. Die Eigenschaft Password erhält nur noch die entsprechenden Attribute:

 

    public class LoginInfo

    {

        private string m_UserName;

        private string m_Password;

 

        [Category("Credentials")]

        public string UserName

        {

            get { return m_UserName; }

            set { m_UserName = value; }

        }

 

        [Category("Credentials")]

        [TypeConverter(typeof(PasswordStringConverter))]

        [Editor(typeof(PasswordEditor), typeof(UITypeEditor))]

        public string Password

        {

            get { return m_Password; }

            set { m_Password = value; }

        }

    }

 


VS Express breaks Delphi 2005

November 15, 2005 21:14 by Jens
Nach der Installation von VB 2005 Express und C# 2005 Express bekam ich beim Start von Delphi 2005 diese Zugriffsverletzung:

Access violation at address 061577BE in module 'htmlhelp290.bpl'. Read of address 00000018.

Aus einer Newsgroup bekam ich einen Tipp, der das Problem tatsächlich behob. Man muss den String-Wert von "AppID" im Schlüssel HKEY_CLASSES_ROOT\AppID\dexplore.exe ändern zu: {4A79114D-19E4-11d3-B86B-00C04F79F802}

Eric Sink über Fehler in Software

November 13, 2005 21:12 by Jens

Eric Sink schrieb einen interessanten Artikel über Bugs in ausgelieferter Software. Seine These lautet, dass Softwareentwickler bzw. -firmen auch Programme dann ausliefern sollten, wenn sie bekannte Bugs enthalten.

Er begründet das so:

  • Man weiß genau, welche Bugs akzeptabel sind und welche nicht
  • Besser ein Produkt veröffentlichen, dessen Qualitätslevel bekannt ist, als ein Produkt, das "vermeintlich" fehlerfrei ist
  • Das Risiko neue und schlimmere Fehler einzubauen beim Versuch einen bekannten Fehler zu entfernen ist könnte zu groß sein

Wie entscheidet man, ob ein Fehler entfernt werden soll oder nicht?
Sink entscheidet das mit Hilfe von vier Fragen:

  1. Wie groß sind die Auswirkungen wenn der Fehler auftritt? (Schweregrad)
  2. Wie oft tritt der Fehler auf? (Häufigkeit)
  3. Wie groß ist der Aufwand, den Fehler zu beseitigen? (Kosten)
  4. Wie riskant ist es, den Fehler zu beheben? (Risiko)

Die Antworten der ersten beiden Fragen lassen sich in ein Diagramm eintragen. Damit kann man visuell entscheiden, ob ein Fehler es wert ist, behoben zu werden:


Der rote Punkt markiert einen Fehler, der behoben werden sollte, da dieser kritische Fehler häufig auftritt. Den Fehler, der durch den grünen Punkt repräsentiert wird kann man vorerst getrost in Ruhe lassen, da er kaum von Bedeutung ist.

Die ersten beiden Fragen geben eine Vorentscheidung darüber, ob der Fehler behoben werden soll oder nicht. Ist die Antwort "Ja", so dienen die beiden anderen Fragen dazu, diese Entscheidung nochmal zu überdenken. Immerhin könnten die Kosten, den Fehler zu beseitigen den Nutzen übersteigen könnten. Und das Risiko neue Fehler einzuführen könnte zu hoch sein.

Sink hebt aber noch hervor, dass die Antworten auf die vier Fragen immer im Kontext des Marktsegments zu finden sein sollten. Die Qualitätserwartungen können sich teilweise deutlich unterscheiden. Er sagt weiter, dass zwar niemand kaputte Produkte haben will, aber jeder sollte auch wissen, dass es keine fehlerfreie Software gibt.

Sink nennt noch einen weiteren Grund dafür, bewusst Software mit Fehlern auszuliefern. Wenn man die Auslieferung herauszögert, weil man jeden bekannten Bug entfernen möchte, ist man auf dem Markt benachteiligt. Man sollte lieber ein Produkt ausliefern, das ein akzeptables Qualitätslevel (auch mit Fehlern) besitzt, als ein Produkt deutlich verspätet auszuliefern, dessen Qualität höher als für den Markt überhaupt nötig ist. 

Eric Wise: Self documenting Code

November 6, 2005 21:20 by Jens

Eric Wise hat einen Blogeintrag über "self documenting code" geschrieben. Er beschränkt sich darin fast ausschließlich auf die Namensgebung von Methoden und Variablen. Er hat nennt zwei Faustregeln:

  1. If it looks like a cow and acts like a cow, call it a cow.
  2. Once you call it a cow, make sure you always call it a cow.

Dem gibt es eigentlich kaum noch etwas hinzuzufügen.

Ich bin der Meinung, dass sich Quelltext lesen lassen sollte wie ein Roman - wie ein Groschenroman. Denn langweilig sollte er sein. Quelltext sollte keine interessanten, spannenden oder trickreichen Kniffe enthalten. Nur so bleibt er lesbar und leicht verständlich.