October 2007 Blog Posts
[OT] Sono in sciopero della fame
Ero titubante se fare un post di questo tipo, per il fatto che non venga capito o travisato. Ma voglio chiarire da subito: non si tratta di un post politico. Purtroppo esprimere pubblicamente le proprie idee politiche crea sempre problemi.

Vorrei citare cifre o statistiche che offrano una visione sul problema che vorrei finalmente fosse risolto. Ma non credo siano importanti. Può sembrare presuntuoso pensare di risolvere un problema di questo genere, da soli. infatti il mio è solo un contributo a quello che penso dovrebbe essere intollerabile sia dal punto di vista etico che umano.

Il problema a cui mi riferisco è il fatto che muoiano di fame 11 bambini ogni minuto, basta contare fino a 6 e un altro si è spento. Durante la scrittura di questo post ne sono già morti più di 50. E' una cosa ignobile, uno scempio che non dovremmo più sopportare. Questo non è un problema come l'inquinamento o la gestione economica di uno stato, le cui soluzioni non sono banali. E' un problema che potremmo risolvere domani! Ma come tutte le cose, anche giustamente, almeno da un certo punto di vista, non ci tangono, finchè poi non si verifica qualcosa per cui dobbiamo prestarle attenzione. Tipico esempio? Il rumorino della lavatrice che non risolviamo immediatamente e per il quale dopo qualche giorno ci ritroviamo la casa allagata.

Quindi non accuso nessuno, in qualche modo è nella nostra natura non considerare i problemi che non percepiamo o dei quali ci sfugge l'importanza.

Per questo motivo 3 giorni e mezzo fa; ho deciso di iniziare uno sciopero della fame. Non so cosa possa portare, se possa essere utile davvero, ma comunque al termine avrò almeno capito cosa significa non poter soddisfare lo stimolo impellente di riempirmi la pancia. Io sono una persona che mangia comunque poco, per motivi salutistici, considerato che l'obesità e le malattie cardio-vascolari sono le principali cause di morte del mondo occidentale. Ma non mangiare niente, è diverso, ci permette di capire quanto siamo fragili.

Quindi vi chiedo di non trasformare questa iniziativa in qualcosa di ideologico; non lo è! Nessuno è giudicato e non penso di essere superiore a nessuno.

Grazie per l'attenzione.

Matteo Migliore.
3 Comments Filed Under [ OT - Out of topic ]
Implementare un custom Membership provider con ASP.NET
Un esempio su come scrivere un custom Membership provider per ASP.NET che consenta di validare correttamente la password nei vari metodi.
In particolare se la password non rispetta i vincoli imposti dal provider, la cosa da fare è lanciare un eccezione, che viene poi intercettata dai Login control e viene comunicato all'utente il problema. Bisogna inoltre invocare il metodo OnValidatingPassword, nel caso in cui la password sia corretta, per scatenare l'evento ValidatingPassword del provider.
Qui il codice:
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
    PasswordCheck passwordCheck = IsValidPassword(newPassword);
    if (passwordCheck == PasswordCheck.MinRequiredPasswordLength)
        throw new ArgumentException("Password does not respects min required lenght.");

    if (passwordCheck == PasswordCheck.NonAlphanumericCharacters)
        throw new ArgumentException("Password does not respects alphanumeric lenght.");

    ValidatePasswordEventArgs e = new ValidatePasswordEventArgs(username, newPassword, false);
    OnValidatingPassword(e);
    return true;
}

public override MembershipUser CreateUser
    (string username, string password, 
     string email, string passwordQuestion, 
     string passwordAnswer, bool isApproved, 
     object providerUserKey, out MembershipCreateStatus status)
{
    if (IsValidPassword(password) != PasswordCheck.Valid) {
        status = MembershipCreateStatus.InvalidPassword;
        return null;
    }

    ValidatePasswordEventArgs e = new ValidatePasswordEventArgs(username, password, true);
    OnValidatingPassword(e);

    DateTime now = DateTime.Now;
    status = MembershipCreateStatus.Success;
    MembershipUser user = new MembershipUser
        (this.GetType().Name, username, Guid.NewGuid(), 
         email, passwordQuestion, string.Empty, true, false, 
         now, now, now, now, now);
    HttpContext.Current.Cache[user.UserName] = user;
    return user;
}

private enum PasswordCheck { 
    Valid = 0,
    NonAlphanumericCharacters = 2,
    MinRequiredPasswordLength = 4
}

private PasswordCheck IsValidPassword(string password) {
    if (password.Length < this.MinRequiredPasswordLength)
        return PasswordCheck.MinRequiredPasswordLength;

    int nonAlphanumericCharacters = 0;
    for (int i = 0; i < password.Length; i++)
    {
        if (!char.IsLetterOrDigit(password, i))
            nonAlphanumericCharacters++;
    }

    if (nonAlphanumericCharacters < this.MinRequiredNonAlphanumericCharacters)
        return PasswordCheck.NonAlphanumericCharacters;

    return PasswordCheck.Valid;
}

public override MembershipUser GetUser(string username, bool userIsOnline)
{
    MembershipUser user = HttpContext.Current.Cache[username] as MembershipUser;
    return user;
}

public override bool ValidateUser(string username, string password)
{
    MembershipUser user = HttpContext.Current.Cache[username] as MembershipUser;
    return ((user != null) && user.GetPassword().Equals(password));
}

Matteo Migliore.
Disegnare nella Nonclient area di una Form con GDI+ e C#
Oggi un amico mi ha chiesto un esempio di come disegnare nella Nonclient area di una Windows Forms, cioè l'area normalmente in cui non è possibile posizionare controlli; tipicamente i bordi e la title-bar o caption. La soluzione prevede l'utilizzo di interoperability per poter richiamare direttamente le GDI API del sistema operativo.

Bisogna quindi intercettare i messaggi inviati dall'OS alla form eseguendo l'override del metodo WndProc e verificare che il messaggio sia WM_NCPAINT. A questo punto si può gestire il messaggio, ottenere un HDC con l'API GetHdc e quindi usare GDI+ Managed.

Qui una classe che wrappa le API necessarie, e un enum con alcun messaggi Windows:
internal class GdiNativeMethods
{
    [DllImport("user32.dll")]
    public extern static IntPtr GetDesktopWindow();

    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowDC(IntPtr hwnd);

    [DllImport("user32.dll")]
    public static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc);

    [DllImport("gdi32.dll")]
    public static extern UInt64 BitBlt
    (IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, System.Int32 dwRop);
}

internal enum WM_Message
{
    WM_NCCALCSIZE = 131,
    WM_NCPAINT = 133,
    WM_NCHITTEST = 132,
    WM_NCLBUTTONDOWN = 161,
}

Qui invece il codice che utilizza GDI+ e permette di disegnare intercettando i messaggi da WndProc:
public partial class Main : Form
{
    public Main()
    {
        InitializeComponent();

        base.SetStyle(ControlStyles.DoubleBuffer, true);
        base.SetStyle(ControlStyles.ResizeRedraw, true);
        base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        base.SetStyle(ControlStyles.UserPaint, true);
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg) {
            case (int)WM_Message.WM_NCPAINT:
                IntPtr hDC = GdiNativeMethods.GetWindowDC(this.Handle);
                Graphics gr = Graphics.FromHdc(hDC);

                int penSize = 3;
                gr.DrawRectangle(new Pen(Brushes.Red, penSize), 0, 0, this.Width - 1, this.Height - 1);
                gr.DrawLine(new Pen(Brushes.Green, penSize), 0, 0, this.Width - 1, 0);                    
                GdiNativeMethods.ReleaseDC(m.HWnd, hDC);
                m.Result = IntPtr.Zero;
                break;
        }            
    }
}

Qui è possibile scaricare l'applicazione di esempio: GDIPlusUnManaged

Matteo Migliore.
Raggruppare i file che compongono una partial class in VS2005
Vi siete mai chiesti come ragguppare sotto lo stesso nodo i file che compongono una partial class in Visual Studio 2005? Io sì ma come tante cose l'ho sempre lasciata in secondo piano perchè sicuramente non cambierà la vita a nessuno :-). Cercando online ho trovato questo articolo: How To Properly Group Partial Class Files in Visual Studio 2005. La cosa divertente e di cui mi accorgo ora, avendo linkato "partial class" su MSDN è che c'è un commento che spiega la stessa cosa :-). Ovviamente è possibile farlo per qualsiasi classe, non solo per WebForm.
Nota: se avete classi che si trovano in subfolder all'interno del project, il riferimento dei file figli al file parent deve essere specificato solo con il nome del file parent, non con tutto il percorso.

Cioè se la struttura fosse:
- Project
    - Foo
        - Foo.cs
        - Foo.Partial.cs

La definizione sarà:
<Compile Include="Foo\Foo.cs" />
<Compile Include="Foo\Foo.Partial.cs">
    <DependentUpon>Foo.cs</DependentUpon>
</Compile>
Il file da modificare è il file di progetto.