Click here to Skip to main content
15,880,608 members
Articles / Desktop Programming / Windows Forms

Metro UI (Zune like) Interface (form)

Rate me:
Please Sign up or sign in to vote.
4.81/5 (30 votes)
26 Dec 2010CPOL3 min read 180K   15K   74   48
How to create a Zune UI Borderless form in VB.NET
zuneui.jpg

Introduction

The future of Windows Interfaces is probably the Zune-like ones, with a borderless form and some controls inside of it. The problem is: if you're using WindowsForm, creating that borderless form with shadows and resizing stuff isn't as easy as it seems. This article will show you how to create those forms using a bit of DWM and some other Windows APIs.

Background

To create the desired effect, we will need to extend the non-client area, cut off the Aero's glass from the Window, and handle some resizing and moving events. Luckily, José Mendez has shown us in his article how to do some of these things.

Of course, "the non-client area trick" only works if Aero is turned on. But I've handled it on my code. Let's take a look:

Using the Code

I've tried to create a Form for you to inherit it, making it easy for you to use my code. Unluckily, the resize thing must be changed if you want to extend that functionality into a panel or some other control. So I preferred to give my code for you to add it inside your own form.

Also, you need to have a form's text and set the FormBorderStyle property to "Sizable" to make everything work properly. DWM can't extend the glass and the client-area if it can't find one, so removing your form's text + controlbox or setting the FormBorderStyle to anything else other than "Sizable" would bring you some unexpected bugs. Keep that it mind.

First, you'll need to add both classes DWM.vb and WinApi.vb to your project. Then, use this code to give your form a Zune (Metro) like shape:

VB.NET
#Region "Fields"
    Private dwmMargins As Dwm.MARGINS
    Private _marginOk As Boolean
    Private _aeroEnabled As Boolean = False
#End Region
#Region "Ctor"
    Public Sub New()
        SetStyle(ControlStyles.ResizeRedraw, True)

        InitializeComponent()

        DoubleBuffered = True

    End Sub
#End Region
#Region "Props"
    Public ReadOnly Property AeroEnabled() As Boolean
        Get
            Return _aeroEnabled
        End Get
    End Property
#End Region
#Region "Methods"
    Public Shared Function LoWord(ByVal dwValue As Integer) As Integer
        Return dwValue And &HFFFF
    End Function
    ''' <summary>
    ''' Equivalent to the HiWord C Macro
    ''' </summary>
    ''' <param name="dwValue"></param>
    ''' <returns></returns>
    Public Shared Function HiWord(ByVal dwValue As Integer) As Integer
        Return (dwValue >> 16) And &HFFFF
    End Function
#End Region

    Private Sub Form1_Activated(ByVal sender As Object, _
	ByVal e As System.EventArgs) Handles Me.Activated
        Dwm.DwmExtendFrameIntoClientArea(Me.Handle, dwmMargins)
    End Sub

    Protected Overloads Overrides Sub WndProc(ByRef m As Message)
        Dim WM_NCCALCSIZE As Integer = &H83
        Dim WM_NCHITTEST As Integer = &H84
        Dim result As IntPtr

        Dim dwmHandled As Integer = Dwm.DwmDefWindowProc_
		(m.HWnd, m.Msg, m.WParam, m.LParam, result)

        If dwmHandled = 1 Then
            m.Result = result
            Exit Sub
        End If

        If m.Msg = WM_NCCALCSIZE AndAlso CInt(m.WParam) = 1 Then
            Dim nccsp As NCCALCSIZE_PARAMS = _
              DirectCast(Marshal.PtrToStructure(m.LParam, _
              GetType(NCCALCSIZE_PARAMS)), NCCALCSIZE_PARAMS)

            ' Adjust (shrink) the client rectangle to accommodate the border:
            nccsp.rect0.Top += 0
            nccsp.rect0.Bottom += 0
            nccsp.rect0.Left += 0
            nccsp.rect0.Right += 0

            If Not _marginOk Then
                'Set what client area would be for passing to 
                'DwmExtendIntoClientArea. Also remember that at least 
                'one of these values NEEDS TO BE > 1, else it won't work.
                dwmMargins.cyTopHeight = 0
                dwmMargins.cxLeftWidth = 0
                dwmMargins.cyBottomHeight = 1
                dwmMargins.cxRightWidth = 0
                _marginOk = True
            End If

            Marshal.StructureToPtr(nccsp, m.LParam, False)

            m.Result = IntPtr.Zero
        ElseIf m.Msg = WM_NCHITTEST AndAlso CInt(m.Result) = 0 Then
            m.Result = HitTestNCA(m.HWnd, m.WParam, m.LParam)
        Else
            MyBase.WndProc(m)
        End If
    End Sub

    Private Function HitTestNCA(ByVal hwnd As IntPtr, ByVal wparam _
                                      As IntPtr, ByVal lparam As IntPtr) As IntPtr
        Dim HTNOWHERE As Integer = 0
        Dim HTCLIENT As Integer = 1
        Dim HTCAPTION As Integer = 2
        Dim HTGROWBOX As Integer = 4
        Dim HTSIZE As Integer = HTGROWBOX
        Dim HTMINBUTTON As Integer = 8
        Dim HTMAXBUTTON As Integer = 9
        Dim HTLEFT As Integer = 10
        Dim HTRIGHT As Integer = 11
        Dim HTTOP As Integer = 12
        Dim HTTOPLEFT As Integer = 13
        Dim HTTOPRIGHT As Integer = 14
        Dim HTBOTTOM As Integer = 15
        Dim HTBOTTOMLEFT As Integer = 16
        Dim HTBOTTOMRIGHT As Integer = 17
        Dim HTREDUCE As Integer = HTMINBUTTON
        Dim HTZOOM As Integer = HTMAXBUTTON
        Dim HTSIZEFIRST As Integer = HTLEFT
        Dim HTSIZELAST As Integer = HTBOTTOMRIGHT

        Dim p As New Point(LoWord(CInt(lparam)), HiWord(CInt(lparam)))

        Dim topleft As Rectangle = RectangleToScreen(New Rectangle(0, 0, _
                                   dwmMargins.cxLeftWidth, dwmMargins.cxLeftWidth))

        If topleft.Contains(p) Then
            Return New IntPtr(HTTOPLEFT)
        End If

        Dim topright As Rectangle = _
          RectangleToScreen(New Rectangle(Width - dwmMargins.cxRightWidth, 0, _
          dwmMargins.cxRightWidth, dwmMargins.cxRightWidth))

        If topright.Contains(p) Then
            Return New IntPtr(HTTOPRIGHT)
        End If

        Dim botleft As Rectangle = _
           RectangleToScreen(New Rectangle(0, Height - dwmMargins.cyBottomHeight, _
           dwmMargins.cxLeftWidth, dwmMargins.cyBottomHeight))

        If botleft.Contains(p) Then
            Return New IntPtr(HTBOTTOMLEFT)
        End If

        Dim botright As Rectangle = _
            RectangleToScreen(New Rectangle(Width - dwmMargins.cxRightWidth, _
            Height - dwmMargins.cyBottomHeight, _
            dwmMargins.cxRightWidth, dwmMargins.cyBottomHeight))

        If botright.Contains(p) Then
            Return New IntPtr(HTBOTTOMRIGHT)
        End If

        Dim top As Rectangle = _
            RectangleToScreen(New Rectangle(0, 0, Width, dwmMargins.cxLeftWidth))

        If top.Contains(p) Then
            Return New IntPtr(HTTOP)
        End If

        Dim cap As Rectangle = _
            RectangleToScreen(New Rectangle(0, dwmMargins.cxLeftWidth, _
            Width, dwmMargins.cyTopHeight - dwmMargins.cxLeftWidth))

        If cap.Contains(p) Then
            Return New IntPtr(HTCAPTION)
        End If

        Dim left As Rectangle = _
            RectangleToScreen(New Rectangle(0, 0, dwmMargins.cxLeftWidth, Height))

        If left.Contains(p) Then
            Return New IntPtr(HTLEFT)
        End If

        Dim right As Rectangle = _
            RectangleToScreen(New Rectangle(Width - dwmMargins.cxRightWidth, _
            0, dwmMargins.cxRightWidth, Height))

        If right.Contains(p) Then
            Return New IntPtr(HTRIGHT)
        End If

        Dim bottom As Rectangle = _
            RectangleToScreen(New Rectangle(0, Height - dwmMargins.cyBottomHeight, _
            Width, dwmMargins.cyBottomHeight))

        If bottom.Contains(p) Then
            Return New IntPtr(HTBOTTOM)
        End If

        Return New IntPtr(HTCLIENT)
    End Function		

At:

VB.NET
dwmMargins.cyTopHeight = 0
                dwmMargins.cxLeftWidth = 0
                dwmMargins.cyBottomHeight = 1
                dwmMargins.cxRightWidth = 0 

You need to have AT LEAST one value higher than 1.

You should have something like this by now:

Sem_t_tulo.png

NICE! Now you have a Zune like shape, with shadows and everything. What else will we need? The resizing stuff, of course!

VB.NET
Private Const BorderWidth As Integer = 6
    Private _resizeDir As ResizeDirection = ResizeDirection.None
    Private Sub Form1_MouseDown(ByVal sender As System.Object, _
	ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            If Me.Width - BorderWidth > e.Location.X AndAlso _
		e.Location.X > BorderWidth AndAlso e.Location.Y > BorderWidth Then
                MoveControl(Me.Handle)
            Else
                If Me.WindowState <> FormWindowState.Maximized Then
                    ResizeForm(resizeDir)
                End If
            End If
        End If
    End Sub
    Public Enum ResizeDirection
        None = 0
        Left = 1
        TopLeft = 2
        Top = 4
        TopRight = 8
        Right = 16
        BottomRight = 32
        Bottom = 64
        BottomLeft = 128
    End Enum
    Private Property resizeDir() As ResizeDirection
        Get
            Return _resizeDir
        End Get
        Set(ByVal value As ResizeDirection)
            _resizeDir = value
            'Change cursor
            Select Case value
                Case ResizeDirection.Left
                    Me.Cursor = Cursors.SizeWE
                Case ResizeDirection.Right
                    Me.Cursor = Cursors.SizeWE
                Case ResizeDirection.Top
                    Me.Cursor = Cursors.SizeNS
                Case ResizeDirection.Bottom
                    Me.Cursor = Cursors.SizeNS
                Case ResizeDirection.BottomLeft
                    Me.Cursor = Cursors.SizeNESW

                Case ResizeDirection.TopRight
                    Me.Cursor = Cursors.SizeNESW

                Case ResizeDirection.BottomRight
                    Me.Cursor = Cursors.SizeNWSE

                Case ResizeDirection.TopLeft
                    Me.Cursor = Cursors.SizeNWSE

                Case Else
                    Me.Cursor = Cursors.Default
            End Select
        End Set
    End Property

    Private Sub Form1_MouseMove(ByVal sender As System.Object, _
	ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
        'Calculate which direction to resize based on mouse position

        If e.Location.X < BorderWidth And e.Location.Y < BorderWidth Then
            resizeDir = ResizeDirection.TopLeft

        ElseIf e.Location.X < BorderWidth And e.Location.Y > Me.Height - BorderWidth Then
            resizeDir = ResizeDirection.BottomLeft

        ElseIf e.Location.X > Me.Width - BorderWidth And e.Location.Y > _
		Me.Height - BorderWidth Then
            resizeDir = ResizeDirection.BottomRight

        ElseIf e.Location.X > Me.Width - BorderWidth And e.Location.Y < BorderWidth Then
            resizeDir = ResizeDirection.TopRight

        ElseIf e.Location.X < BorderWidth Then
            resizeDir = ResizeDirection.Left

        ElseIf e.Location.X > Me.Width - BorderWidth Then
            resizeDir = ResizeDirection.Right

        ElseIf e.Location.Y < BorderWidth Then
            resizeDir = ResizeDirection.Top

        ElseIf e.Location.Y > Me.Height - BorderWidth Then
            resizeDir = ResizeDirection.Bottom

        Else
            resizeDir = ResizeDirection.None
        End If
    End Sub

    Private Sub MoveControl(ByVal hWnd As IntPtr)
        ReleaseCapture()
        SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0)
    End Sub

    Private Sub ResizeForm(ByVal direction As ResizeDirection)
        Dim dir As Integer = -1
        Select Case direction
            Case ResizeDirection.Left
                dir = HTLEFT
            Case ResizeDirection.TopLeft
                dir = HTTOPLEFT
            Case ResizeDirection.Top
                dir = HTTOP
            Case ResizeDirection.TopRight
                dir = HTTOPRIGHT
            Case ResizeDirection.Right
                dir = HTRIGHT
            Case ResizeDirection.BottomRight
                dir = HTBOTTOMRIGHT
            Case ResizeDirection.Bottom
                dir = HTBOTTOM
            Case ResizeDirection.BottomLeft
                dir = HTBOTTOMLEFT
        End Select

        If dir <> -1 Then
            ReleaseCapture()
            SendMessage(Me.Handle, WM_NCLBUTTONDOWN, dir, 0)
        End If

    End Sub

    <DllImport("user32.dll")> _
    Public Shared Function ReleaseCapture() As Boolean
    End Function

    <DllImport("user32.dll")> _
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, _
	ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) _
	As Integer
    End Function

    Private Const WM_NCLBUTTONDOWN As Integer = &HA1
    Private Const HTBORDER As Integer = 18
    Private Const HTBOTTOM As Integer = 15
    Private Const HTBOTTOMLEFT As Integer = 16
    Private Const HTBOTTOMRIGHT As Integer = 17 
    Private Const HTCAPTION As Integer = 2
    Private Const HTLEFT As Integer = 10
    Private Const HTRIGHT As Integer = 11
    Private Const HTTOP As Integer = 12
    Private Const HTTOPLEFT As Integer = 13
    Private Const HTTOPRIGHT As Integer = 14  

Nice, everything should be working by now. :D

Ah, you can also increase and decrease border size by changing the "BorderWidth" value to whatever you want. Just remember that it needs to be an integer value.

The Last Problem

Everything works fine if you don't overlay any border, but if you do, there's a simple way to fix it. All you have to do is to add your control's mousedown and mousemove events on the Form1_MouseDown and Form1_MouseMove events. That's all. :D

A Bit of Work...

With a little bit more of work and my code, you can easily create full-featured and amazing interfaces. And the coolest part is that now, you'd be able to create everything on your form! Want a Mac OS X window? Just create it! Want a Zune Clone interface? Just copy it! That simple! :D

I've created a simple demonstration of what can be made without much work (that's just a preview to show something different than a black window). Check this out:

zuneui.jpg

That's the Zune interface.

geet.jpg

And this is a simple example of what can be made with a little work. That's just a sample application I've created within 5 minutes to test this article, and as you can see, it's pretty much the same as the Zune UI.

Points of Interest

It is cool to develop this kind of interface since you can have full control over your form without losing some pretty cool Vista/7 effects such as shadows.

By the way, I'd like to say sorry for my bad English.

Peace.

History

  • 1st code revision published

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Brazil Brazil
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: bug Pin
Jorge-TG4-Aug-12 18:42
Jorge-TG4-Aug-12 18:42 
Questionfull code Pin
Luige César Salvi1-Dec-11 6:27
Luige César Salvi1-Dec-11 6:27 
BugTitle Bar Comes Up! Pin
Member 843837728-Nov-11 10:01
Member 843837728-Nov-11 10:01 
GeneralMy vote of 5 Pin
Member 843837727-Nov-11 17:19
Member 843837727-Nov-11 17:19 
QuestionMinimized Form Problem Pin
oohoo_u28-Oct-11 6:42
oohoo_u28-Oct-11 6:42 
GeneralMy vote of 5 Pin
megagonzo5-Oct-11 22:42
megagonzo5-Oct-11 22:42 
QuestionMaximize Pin
sathya.cs6-Sep-11 23:31
sathya.cs6-Sep-11 23:31 
Questionc# Pin
identy30-Aug-11 12:05
identy30-Aug-11 12:05 
Window
C#
public _Window()
    : base() {

    SetStyle(ControlStyles.ResizeRedraw, true);

    InitializeComponent();

    DoubleBuffered = true;


}

#region Metro Design

public const int BorderWidth = 6;

private WindowManager.MARGINS Margins;
private bool IsMargin = false;

private Native.ResizeDirection _ResizeDirection = Native.ResizeDirection.None;

public static int LoWord(int dwValue) {
    return dwValue & 0xFFFF;
}
public static int HiWord(int dwValue) {
    return (dwValue >> 16) & 0xFFFF;
}

private void Window_Activated(object sender, EventArgs e) {
    WindowManager.DwmExtendFrameIntoClientArea(this.Handle, ref Margins);
}

protected override void WndProc(ref Message message) {
    int WM_NCCALCSIZE = 0x83;
    int WM_NCHITTEST = 0x84;

    IntPtr result = IntPtr.Zero;

    int dwmHandled = WindowManager.DwmDefWindowProc(message.HWnd, message.Msg, message.WParam, message.LParam, ref result);

    if (dwmHandled == 1) {
        message.Result = result;
        return;
    }

    if (message.Msg == WM_NCCALCSIZE && ((int)message.WParam) == 1) {

        Native.NCCALCSIZE_PARAMS nccsp = (Native.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(message.LParam, typeof(Native.NCCALCSIZE_PARAMS));

        nccsp.rect0.Top += 0;
        nccsp.rect0.Bottom += 0;
        nccsp.rect0.Left += 0;
        nccsp.rect0.Right += 0;

        if (!IsMargin) {
            Margins.cyTopHeight = 3;
            Margins.cxLeftWidth = 3;
            Margins.cyBottomHeight = 3;
            Margins.cxRightWidth = 3;
            IsMargin = true;
        }

        Marshal.StructureToPtr(nccsp, message.LParam, false);

        message.Result = IntPtr.Zero;

    }
    else if (message.Msg == WM_NCHITTEST && ((int)message.Result) == 0) {
        message.Result = Hit(message.HWnd, message.WParam, message.LParam);
    }
    else {
        base.WndProc(ref message);
    }

}

private IntPtr Hit(IntPtr hwnd, IntPtr wparam, IntPtr lparam) {
    int HTNOWHERE = 0;
    int HTCLIENT = 1;
    int HTCAPTION = 2;
    int HTGROWBOX = 4;
    int HTSIZE = HTGROWBOX;
    int HTMINBUTTON = 8;
    int HTMAXBUTTON = 9;
    int HTLEFT = 10;
    int HTRIGHT = 11;
    int HTTOP = 12;
    int HTTOPLEFT = 13;
    int HTTOPRIGHT = 14;
    int HTBOTTOM = 15;
    int HTBOTTOMLEFT = 16;
    int HTBOTTOMRIGHT = 17;
    int HTREDUCE = HTMINBUTTON;
    int HTZOOM = HTMAXBUTTON;
    int HTSIZEFIRST = HTLEFT;
    int HTSIZELAST = HTBOTTOMRIGHT;

    Point p = new Point(LoWord((int)(lparam)), HiWord((int)(lparam)));

    Rectangle topleft = RectangleToScreen(new Rectangle(0, 0, Margins.cxLeftWidth, Margins.cxLeftWidth));

    if (topleft.Contains(p))
        return new IntPtr(HTTOPLEFT);

    Rectangle topright = RectangleToScreen(new Rectangle(Width - Margins.cxRightWidth, 0, Margins.cxRightWidth, Margins.cxRightWidth));

    if (topright.Contains(p))
        return new IntPtr(HTTOPRIGHT);

    Rectangle botleft = RectangleToScreen(new Rectangle(0, Height - Margins.cyBottomHeight, Margins.cxLeftWidth, Margins.cyBottomHeight));

    if (botleft.Contains(p))
        return new IntPtr(HTBOTTOMLEFT);

    Rectangle botright = RectangleToScreen(new Rectangle(Width - Margins.cxRightWidth, Height - Margins.cyBottomHeight, Margins.cxRightWidth, Margins.cyBottomHeight));

    if (botright.Contains(p))
        return new IntPtr(HTBOTTOMRIGHT);

    Rectangle top = RectangleToScreen(new Rectangle(0, 0, Width, Margins.cxLeftWidth));

    if (top.Contains(p))
        return new IntPtr(HTTOP);

    Rectangle cap = RectangleToScreen(new Rectangle(0, Margins.cxLeftWidth, Width, Margins.cyTopHeight - Margins.cxLeftWidth));

    if (cap.Contains(p))
        return new IntPtr(HTCAPTION);

    Rectangle left = RectangleToScreen(new Rectangle(0, 0, Margins.cxLeftWidth, Height));

    if (left.Contains(p))
        return new IntPtr(HTLEFT);

    Rectangle right = RectangleToScreen(new Rectangle(Width - Margins.cxRightWidth, 0, Margins.cxRightWidth, Height));

    if (right.Contains(p))
        return new IntPtr(HTRIGHT);

    Rectangle bottom = RectangleToScreen(new Rectangle(0, Height - Margins.cyBottomHeight, Width, Margins.cyBottomHeight));

    if (bottom.Contains(p))
        return new IntPtr(HTBOTTOM);

    return new IntPtr(HTCLIENT);

}


private void Window_MouseDown(object sender, MouseEventArgs e) {
    if (e.Button == MouseButtons.Left) {
        if (this.Width - BorderWidth > e.Location.X && e.Location.X > BorderWidth && e.Location.Y > BorderWidth) {
            Native.ReleaseCapture();
            Native.SendMessage(this.Handle, Native.WM_NCLBUTTONDOWN, Native.HTCAPTION, 0);
        }
        else {
            if (this.WindowState != FormWindowState.Maximized) {
                DirectionResize(ResizeDirection);
            }
        }
    }
}
private void Window_MouseMove(object sender, MouseEventArgs e) {
    if (e.Location.X < BorderWidth && e.Location.Y < BorderWidth)
        ResizeDirection = Native.ResizeDirection.TopLeft;
    else if (e.Location.X < BorderWidth && e.Location.Y > this.Height - BorderWidth)
        ResizeDirection = Native.ResizeDirection.BottomLeft;
    else if (e.Location.X > this.Width - BorderWidth && e.Location.Y > this.Height - BorderWidth)
        ResizeDirection = Native.ResizeDirection.BottomRight;
    else if (e.Location.X > this.Width - BorderWidth && e.Location.Y < BorderWidth)
        ResizeDirection = Native.ResizeDirection.TopRight;
    else if (e.Location.X < BorderWidth)
        ResizeDirection = Native.ResizeDirection.Left;
    else if (e.Location.X > this.Width - BorderWidth)
        ResizeDirection = Native.ResizeDirection.Right;
    else if (e.Location.Y < BorderWidth)
        ResizeDirection = Native.ResizeDirection.Top;
    else if (e.Location.Y > this.Height - BorderWidth)
        ResizeDirection = Native.ResizeDirection.Bottom;
    else
        ResizeDirection = Native.ResizeDirection.None;
}

public Native.ResizeDirection ResizeDirection {
    get {
        return _ResizeDirection;
    }
    set {
        _ResizeDirection = value;
        switch (value) {
            case Native.ResizeDirection.Left:
                this.Cursor = Cursors.SizeWE;
                break;
            case Native.ResizeDirection.Right:
                this.Cursor = Cursors.SizeWE;
                break;
            case Native.ResizeDirection.Top:
                this.Cursor = Cursors.SizeNS;
                break;
            case Native.ResizeDirection.Bottom:
                this.Cursor = Cursors.SizeNS;
                break;
            case Native.ResizeDirection.BottomLeft:
                this.Cursor = Cursors.SizeNESW;
                break;
            case Native.ResizeDirection.TopRight:
                this.Cursor = Cursors.SizeNESW;
                break;
            case Native.ResizeDirection.BottomRight:
                this.Cursor = Cursors.SizeNWSE;
                break;
            case Native.ResizeDirection.TopLeft:
                this.Cursor = Cursors.SizeNWSE;
                break;
            default:
                this.Cursor = Cursors.Default;
                break;
        }
    }
}

public void DirectionResize(Native.ResizeDirection direction) {

    int _direction = -1;

    switch (direction) {
        case Native.ResizeDirection.Left:
            _direction = Native.HTLEFT;
            break;
        case Native.ResizeDirection.TopLeft:
            _direction = Native.HTTOPLEFT;
            break;
        case Native.ResizeDirection.Top:
            _direction = Native.HTTOP;
            break;
        case Native.ResizeDirection.TopRight:
            _direction = Native.HTTOPRIGHT;
            break;
        case Native.ResizeDirection.Right:
            _direction = Native.HTRIGHT;
            break;
        case Native.ResizeDirection.BottomRight:
            _direction = Native.HTBOTTOMRIGHT;
            break;
        case Native.ResizeDirection.Bottom:
            _direction = Native.HTBOTTOM;
            break;
        case Native.ResizeDirection.BottomLeft:
            _direction = Native.HTBOTTOMLEFT;
            break;
    }

    if (_direction != -1) {
        Native.ReleaseCapture();
        Native.SendMessage(this.Handle, Native.WM_NCLBUTTONDOWN, _direction, 0);
    }

}

#endregion

Native
C#
public class Native {

    // This is the default layout for a structure
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    // This is the default layout for a structure
    [StructLayout(LayoutKind.Sequential)]
    public struct NCCALCSIZE_PARAMS {
        public RECT rect0;
        public RECT rect1;
        public RECT rect2;
        // Can't use an array here so simulate one
        public IntPtr lppos;
    }

    public enum Win32Messages {
        WM_NULL = 0x0,
        WM_CREATE = 0x1,
        WM_DESTROY = 0x2,
        WM_MOVE = 0x3,
        WM_SIZE = 0x5,
        WM_ACTIVATE = 0x6,
        WM_SETFOCUS = 0x7,
        WM_KILLFOCUS = 0x8,
        WM_ENABLE = 0xA,
        WM_SETREDRAW = 0xB,
        WM_SETTEXT = 0xC,
        WM_GETTEXT = 0xD,
        WM_GETTEXTLENGTH = 0xE,
        WM_PAINT = 0xF,
        WM_CLOSE = 0x10,
        WM_QUERYENDSESSION = 0x11,
        WM_QUERYOPEN = 0x13,
        WM_ENDSESSION = 0x16,
        WM_QUIT = 0x12,
        WM_ERASEBKGND = 0x14,
        WM_SYSCOLORCHANGE = 0x15,
        WM_SHOWWINDOW = 0x18,
        WM_WININICHANGE = 0x1A,
        WM_SETTINGCHANGE = WM_WININICHANGE,
        WM_DEVMODECHANGE = 0x1B,
        WM_ACTIVATEAPP = 0x1C,
        WM_FONTCHANGE = 0x1D,
        WM_TIMECHANGE = 0x1E,
        WM_CANCELMODE = 0x1F,
        WM_SETCURSOR = 0x20,
        WM_MOUSEACTIVATE = 0x21,
        WM_CHILDACTIVATE = 0x22,
        WM_QUEUESYNC = 0x23,
        WM_GETMINMAXINFO = 0x24,
        WM_PAINTICON = 0x26,
        WM_ICONERASEBKGND = 0x27,
        WM_NEXTDLGCTL = 0x28,
        WM_SPOOLERSTATUS = 0x2A,
        WM_DRAWITEM = 0x2B,
        WM_MEASUREITEM = 0x2C,
        WM_DELETEITEM = 0x2D,
        WM_VKEYTOITEM = 0x2E,
        WM_CHARTOITEM = 0x2F,
        WM_SETFONT = 0x30,
        WM_GETFONT = 0x31,
        WM_SETHOTKEY = 0x32,
        WM_GETHOTKEY = 0x33,
        WM_QUERYDRAGICON = 0x37,
        WM_COMPAREITEM = 0x39,
        WM_GETOBJECT = 0x3D,
        WM_COMPACTING = 0x41,
        WM_COMMNOTIFY = 0x44,
        WM_WINDOWPOSCHANGING = 0x46,
        WM_WINDOWPOSCHANGED = 0x47,
        WM_POWER = 0x48,
        WM_COPYDATA = 0x4A,
        WM_CANCELJOURNAL = 0x4B,
        WM_NOTIFY = 0x4E,
        WM_INPUTLANGCHANGEREQUEST = 0x50,
        WM_INPUTLANGCHANGE = 0x51,
        WM_TCARD = 0x52,
        WM_HELP = 0x53,
        WM_USERCHANGED = 0x54,
        WM_NOTIFYFORMAT = 0x55,
        WM_CONTEXTMENU = 0x7B,
        WM_STYLECHANGING = 0x7C,
        WM_STYLECHANGED = 0x7D,
        WM_DISPLAYCHANGE = 0x7E,
        WM_GETICON = 0x7F,
        WM_SETICON = 0x80,
        WM_NCCREATE = 0x81,
        WM_NCDESTROY = 0x82,
        WM_NCCALCSIZE = 0x83,
        WM_NCHITTEST = 0x84,
        WM_NCPAINT = 0x85,
        WM_NCACTIVATE = 0x86,
        WM_GETDLGCODE = 0x87,
        WM_SYNCPAINT = 0x88,
        WM_NCMOUSEMOVE = 0xA0,
        WM_NCLBUTTONDOWN = 0xA1,
        WM_NCLBUTTONUP = 0xA2,
        WM_NCLBUTTONDBLCLK = 0xA3,
        WM_NCRBUTTONDOWN = 0xA4,
        WM_NCRBUTTONUP = 0xA5,
        WM_NCRBUTTONDBLCLK = 0xA6,
        WM_NCMBUTTONDOWN = 0xA7,
        WM_NCMBUTTONUP = 0xA8,
        WM_NCMBUTTONDBLCLK = 0xA9,
        WM_NCXBUTTONDOWN = 0xAB,
        WM_NCXBUTTONUP = 0xAC,
        WM_NCXBUTTONDBLCLK = 0xAD,
        WM_INPUT = 0xFF,
        WM_KEYFIRST = 0x100,
        WM_KEYDOWN = 0x100,
        WM_KEYUP = 0x101,
        WM_CHAR = 0x102,
        WM_DEADCHAR = 0x103,
        WM_SYSKEYDOWN = 0x104,
        WM_SYSKEYUP = 0x105,
        WM_SYSCHAR = 0x106,
        WM_SYSDEADCHAR = 0x107,
        WM_UNICHAR = 0x109,
        WM_KEYLAST = 0x108,
        WM_IME_STARTCOMPOSITION = 0x10D,
        WM_IME_ENDCOMPOSITION = 0x10E,
        WM_IME_COMPOSITION = 0x10F,
        WM_IME_KEYLAST = 0x10F,
        WM_INITDIALOG = 0x110,
        WM_COMMAND = 0x111,
        WM_SYSCOMMAND = 0x112,
        WM_TIMER = 0x113,
        WM_HSCROLL = 0x114,
        WM_VSCROLL = 0x115,
        WM_INITMENU = 0x116,
        WM_INITMENUPOPUP = 0x117,
        WM_MENUSELECT = 0x11F,
        WM_MENUCHAR = 0x120,
        WM_ENTERIDLE = 0x121,
        WM_MENURBUTTONUP = 0x122,
        WM_MENUDRAG = 0x123,
        WM_MENUGETOBJECT = 0x124,
        WM_UNINITMENUPOPUP = 0x125,
        WM_MENUCOMMAND = 0x126,
        WM_CHANGEUISTATE = 0x127,
        WM_UPDATEUISTATE = 0x128,
        WM_QUERYUISTATE = 0x129,
        WM_CTLCOLOR = 0x19,
        WM_CTLCOLORMSGBOX = 0x132,
        WM_CTLCOLOREDIT = 0x133,
        WM_CTLCOLORLISTBOX = 0x134,
        WM_CTLCOLORBTN = 0x135,
        WM_CTLCOLORDLG = 0x136,
        WM_CTLCOLORSCROLLBAR = 0x137,
        WM_CTLCOLORSTATIC = 0x138,
        WM_MOUSEFIRST = 0x200,
        WM_MOUSEMOVE = 0x200,
        WM_LBUTTONDOWN = 0x201,
        WM_LBUTTONUP = 0x202,
        WM_LBUTTONDBLCLK = 0x203,
        WM_RBUTTONDOWN = 0x204,
        WM_RBUTTONUP = 0x205,
        WM_RBUTTONDBLCLK = 0x206,
        WM_MBUTTONDOWN = 0x207,
        WM_MBUTTONUP = 0x208,
        WM_MBUTTONDBLCLK = 0x209,
        WM_MOUSEWHEEL = 0x20A,
        WM_XBUTTONDOWN = 0x20B,
        WM_XBUTTONUP = 0x20C,
        WM_XBUTTONDBLCLK = 0x20D,
        WM_MOUSELAST = 0x20D,
        WM_PARENTNOTIFY = 0x210,
        WM_ENTERMENULOOP = 0x211,
        WM_EXITMENULOOP = 0x212,
        WM_NEXTMENU = 0x213,
        WM_SIZING = 0x214,
        WM_CAPTURECHANGED = 0x215,
        WM_MOVING = 0x216,
        WM_POWERBROADCAST = 0x218,
        WM_DEVICECHANGE = 0x219,
        WM_MDICREATE = 0x220,
        WM_MDIDESTROY = 0x221,
        WM_MDIACTIVATE = 0x222,
        WM_MDIRESTORE = 0x223,
        WM_MDINEXT = 0x224,
        WM_MDIMAXIMIZE = 0x225,
        WM_MDITILE = 0x226,
        WM_MDICASCADE = 0x227,
        WM_MDIICONARRANGE = 0x228,
        WM_MDIGETACTIVE = 0x229,
        WM_MDISETMENU = 0x230,
        WM_ENTERSIZEMOVE = 0x231,
        WM_EXITSIZEMOVE = 0x232,
        WM_DROPFILES = 0x233,
        WM_MDIREFRESHMENU = 0x234,
        WM_IME_SETCONTEXT = 0x281,
        WM_IME_NOTIFY = 0x282,
        WM_IME_CONTROL = 0x283,
        WM_IME_COMPOSITIONFULL = 0x284,
        WM_IME_SELECT = 0x285,
        WM_IME_CHAR = 0x286,
        WM_IME_REQUEST = 0x288,
        WM_IME_KEYDOWN = 0x290,
        WM_IME_KEYUP = 0x291,
        WM_MOUSEHOVER = 0x2A1,
        WM_MOUSELEAVE = 0x2A3,
        WM_NCMOUSELEAVE = 0x2A2,
        WM_WTSSESSION_CHANGE = 0x2B1,
        WM_TABLET_FIRST = 0x2C0,
        WM_TABLET_LAST = 0x2DF,
        WM_CUT = 0x300,
        WM_COPY = 0x301,
        WM_PASTE = 0x302,
        WM_CLEAR = 0x303,
        WM_UNDO = 0x304,
        WM_RENDERFORMAT = 0x305,
        WM_RENDERALLFORMATS = 0x306,
        WM_DESTROYCLIPBOARD = 0x307,
        WM_DRAWCLIPBOARD = 0x308,
        WM_PAINTCLIPBOARD = 0x309,
        WM_VSCROLLCLIPBOARD = 0x30A,
        WM_SIZECLIPBOARD = 0x30B,
        WM_ASKCBFORMATNAME = 0x30C,
        WM_CHANGECBCHAIN = 0x30D,
        WM_HSCROLLCLIPBOARD = 0x30E,
        WM_QUERYNEWPALETTE = 0x30F,
        WM_PALETTEISCHANGING = 0x310,
        WM_PALETTECHANGED = 0x311,
        WM_HOTKEY = 0x312,
        WM_PRINT = 0x317,
        WM_PRINTCLIENT = 0x318,
        WM_APPCOMMAND = 0x319,
        WM_THEMECHANGED = 0x31A,
        WM_HANDHELDFIRST = 0x358,
        WM_HANDHELDLAST = 0x35F,
        WM_AFXFIRST = 0x360,
        WM_AFXLAST = 0x37F,
        WM_PENWINFIRST = 0x380,
        WM_PENWINLAST = 0x38F,
        WM_USER = 0x400,
        WM_REFLECT = 0x2000,
        WM_APP = 0x8000,

    }

    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HTBORDER = 18;
    public const int HTBOTTOM = 15;
    public const int HTBOTTOMLEFT = 16;
    public const int HTBOTTOMRIGHT = 17;
    public const int HTCAPTION = 2;
    public const int HTLEFT = 10;
    public const int HTRIGHT = 11;
    public const int HTTOP = 12;
    public const int HTTOPLEFT = 13;
    public const int HTTOPRIGHT = 14;

    public enum ResizeDirection {
        None = 0,
        Left = 1,
        TopLeft = 2,
        Top = 4,
        TopRight = 8,
        Right = 16,
        BottomRight = 32,
        Bottom = 64,
        BottomLeft = 128
    }

    [DllImport("user32.dll")]
    public static extern bool ReleaseCapture();

    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

}

WindowManager
C#
public class WindowManager {

    [StructLayout(LayoutKind.Explicit)]
    public struct RECT {
        // Fields
        [FieldOffset(12)]
        public int bottom;
        [FieldOffset(0)]
        public int left;
        [FieldOffset(8)]
        public int right;
        [FieldOffset(4)]
        public int top;

        // Methods
        public RECT(Rectangle rect) {
            this.left = rect.Left;
            this.top = rect.Top;
            this.right = rect.Right;
            this.bottom = rect.Bottom;
        }

        public RECT(int left, int top, int right, int bottom) {
            this.left = left;
            this.top = top;
            this.right = right;
            this.bottom = bottom;
        }

        public void @Set() {
            this.left = InlineAssignHelper<int>(ref this.top, InlineAssignHelper<int>(ref this.right, InlineAssignHelper<int>(ref this.bottom, 0)));
        }

        public void @Set(Rectangle rect) {
            this.left = rect.Left;
            this.top = rect.Top;
            this.right = rect.Right;
            this.bottom = rect.Bottom;
        }

        public void @Set(int left, int top, int right, int bottom) {
            this.left = left;
            this.top = top;
            this.right = right;
            this.bottom = bottom;
        }

        public Rectangle ToRectangle() {
            return new Rectangle(this.left, this.top, this.right - this.left, this.bottom - this.top);
        }

        // Properties
        public int Height {
            get {
                return (this.bottom - this.top);
            }
        }

        public int Width {
            get {
                return (this.right - this.left);
            }
        }

        public Size Size {
            get {
                return new Size(this.Width, this.Height);
            }
        }

        private static T InlineAssignHelper<T>(ref T target, T value) {
            target = value;
            return value;
        }

    }

    // Fields
    public const string DWM_COMPOSED_EVENT_BASE_NAME = "DwmComposedEvent_";
    public const string DWM_COMPOSED_EVENT_NAME_FORMAT = "%s%d";

    public const int DWM_BB_BLURREGION = 2;
    public const int DWM_BB_ENABLE = 1;
    public const int DWM_BB_TRANSITIONONMAXIMIZED = 4;
    public const int DWM_COMPOSED_EVENT_NAME_MAX_LENGTH = unchecked((int)(0x40));
    public const int DWM_FRAME_DURATION_DEFAULT = -1;
    public const int DWM_TNP_OPACITY = 4;
    public const int DWM_TNP_RECTDESTINATION = 1;
    public const int DWM_TNP_RECTSOURCE = 2;
    public const int DWM_TNP_SOURCECLIENTAREAONLY = unchecked((int)(10));
    public const int DWM_TNP_VISIBLE = 8;
    public const int WM_DWMCOMPOSITIONCHANGED = unchecked((int)(0x31E));

    public static bool DwmApiAvailable = (Environment.OSVersion.Version.Major >= 6);

    // Methods
    [DllImport("dwmapi.dll")]
    public static extern int DwmDefWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref IntPtr result);
    [DllImport("dwmapi.dll")]
    public static extern int DwmEnableComposition(int fEnable);
    [DllImport("dwmapi.dll")]
    public static extern int DwmEnableMMCSS(int fEnableMMCSS);
    [DllImport("dwmapi.dll")]
    public static extern int DwmExtendFrameIntoClientArea(IntPtr hdc, ref MARGINS marInset);
    [DllImport("dwmapi.dll")]
    public static extern int DwmGetColorizationColor(ref int pcrColorization, ref int pfOpaqueBlend);
    [DllImport("dwmapi.dll")]
    public static extern int DwmGetCompositionTimingInfo(IntPtr hwnd, ref DWM_TIMING_INFO pTimingInfo);
    [DllImport("dwmapi.dll")]
    public static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, IntPtr pvAttribute, int cbAttribute);
    [DllImport("dwmapi.dll")]
    public static extern int DwmIsCompositionEnabled(ref int pfEnabled);
    [DllImport("dwmapi.dll")]
    public static extern int DwmModifyPreviousDxFrameDuration(IntPtr hwnd, int cRefreshes, int fRelative);
    [DllImport("dwmapi.dll")]
    public static extern int DwmQueryThumbnailSourceSize(IntPtr hThumbnail, ref Size pSize);
    [DllImport("dwmapi.dll")]
    public static extern int DwmRegisterThumbnail(IntPtr hwndDestination, IntPtr hwndSource, ref Size pMinimizedSize, ref IntPtr phThumbnailId);
    [DllImport("dwmapi.dll")]
    public static extern int DwmSetDxFrameDuration(IntPtr hwnd, int cRefreshes);
    [DllImport("dwmapi.dll")]
    public static extern int DwmSetPresentParameters(IntPtr hwnd, ref DWM_PRESENT_PARAMETERS pPresentParams);
    [DllImport("dwmapi.dll")]
    public static extern int DwmSetWindowAttribute(IntPtr hwnd, int dwAttribute, IntPtr pvAttribute, int cbAttribute);
    [DllImport("dwmapi.dll")]
    public static extern int DwmUnregisterThumbnail(IntPtr hThumbnailId);
    [DllImport("dwmapi.dll")]
    public static extern int DwmUpdateThumbnailProperties(IntPtr hThumbnailId, ref DWM_THUMBNAIL_PROPERTIES ptnProperties);

    // Nested Types
    [StructLayout(LayoutKind.Sequential)]
    public struct DWM_BLURBEHIND {
        public int dwFlags;
        public int fEnable;
        public IntPtr hRgnBlur;
        public int fTransitionOnMaximized;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DWM_PRESENT_PARAMETERS {
        public int cbSize;
        public int fQueue;
        public long cRefreshStart;
        public int cBuffer;
        public int fUseSourceRate;
        public UNSIGNED_RATIO rateSource;
        public int cRefreshesPerFrame;
        public DWM_SOURCE_FRAME_SAMPLING eSampling;
    }

    public enum DWM_SOURCE_FRAME_SAMPLING {
        DWM_SOURCE_FRAME_SAMPLING_POINT,
        DWM_SOURCE_FRAME_SAMPLING_COVERAGE,
        DWM_SOURCE_FRAME_SAMPLING_LAST
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DWM_THUMBNAIL_PROPERTIES {
        public int dwFlags;
        public RECT rcDestination;
        public RECT rcSource;
        public byte opacity;
        public int fVisible;
        public int fSourceClientAreaOnly;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DWM_TIMING_INFO {
        public int cbSize;
        public UNSIGNED_RATIO rateRefresh;
        public UNSIGNED_RATIO rateCompose;
        public long qpcVBlank;
        public long cRefresh;
        public long qpcCompose;
        public long cFrame;
        public long cRefreshFrame;
        public long cRefreshConfirmed;
        public int cFlipsOutstanding;
        public long cFrameCurrent;
        public long cFramesAvailable;
        public long cFrameCleared;
        public long cFramesReceived;
        public long cFramesDisplayed;
        public long cFramesDropped;
        public long cFramesMissed;
    }

    public enum DWMNCRENDERINGPOLICY {
        DWMNCRP_USEWINDOWSTYLE,
        DWMNCRP_DISABLED,
        DWMNCRP_ENABLED
    }

    public enum DWMWINDOWATTRIBUTE {
        DWMWA_ALLOW_NCPAINT = 4,
        DWMWA_CAPTION_BUTTON_BOUNDS = 5,
        DWMWA_FLIP3D_POLICY = 8,
        DWMWA_FORCE_ICONIC_REPRESENTATION = 7,
        DWMWA_LAST = 9,
        DWMWA_NCRENDERING_ENABLED = 1,
        DWMWA_NCRENDERING_POLICY = 2,
        DWMWA_NONCLIENT_RTL_LAYOUT = 6,
        DWMWA_TRANSITIONS_FORCEDISABLED = 3
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct UNSIGNED_RATIO {
        public int uiNumerator;
        public int uiDenominator;
    }



    [StructLayout(LayoutKind.Sequential)]
    public struct MARGINS {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;

        public MARGINS(int Left, int Right, int Top, int Bottom) {
            this.cxLeftWidth = Left;
            this.cxRightWidth = Right;
            this.cyTopHeight = Top;
            this.cyBottomHeight = Bottom;
        }
    }


    //''' <summary>
    //''' Do Not Draw The Caption (Text)
    //''' </summary>
    public static uint WTNCA_NODRAWCAPTION = 0x1;
    //''' <summary>
    //''' Do Not Draw the Icon
    //''' </summary>
    public static uint WTNCA_NODRAWICON = 0x2;
    //''' <summary>
    //''' Do Not Show the System Menu
    //''' </summary>
    public static uint WTNCA_NOSYSMENU = 0x4;
    //''' <summary>
    //''' Do Not Mirror the Question mark Symbol
    //''' </summary>
    public static uint WTNCA_NOMIRRORHELP = 0x8;

    //''' <summary>
    //''' The Options of What Attributes to Add/Remove
    //''' </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct WTA_OPTIONS {
        public uint Flags;
        public uint Mask;
    }

    //''' <summary>
    //''' What Type of Attributes? (Only One is Currently Defined)
    //''' </summary>
    public enum WindowThemeAttributeType {
        WTA_NONCLIENT = 1
    }

    //''' <summary>
    //''' Set The Window's Theme Attributes
    //''' </summary>
    //''' <param name="hWnd">The Handle to the Window</param>
    //''' <param name="wtype">What Type of Attributes</param>
    //''' <param name="attributes">The Attributes to Add/Remove</param>
    //''' <param name="size">The Size of the Attributes Struct</param>
    //''' <returns>If The Call Was Successful or Not</returns>
    [DllImport("UxTheme.dll")]
    public static extern int SetWindowThemeAttribute(IntPtr hWnd, WindowThemeAttributeType wtype, ref WTA_OPTIONS attributes, uint size);

}

Wink | ;)
Creador de sueños, títere en una realidad efímera y tardía.

QuestionWhy WinForm and not WPF? Pin
Callon Campbell19-Jan-11 9:01
Callon Campbell19-Jan-11 9:01 
AnswerRe: Why WinForm and not WPF? Pin
Globin25-Jun-12 10:09
Globin25-Jun-12 10:09 
AnswerRe: Why WinForm and not WPF? Pin
geordiemike17-Sep-14 4:16
geordiemike17-Sep-14 4:16 
GeneralProblems Pin
regbnvl25-Dec-10 23:57
regbnvl25-Dec-10 23:57 
GeneralRe: Problems Pin
lipinho26-Dec-10 9:48
lipinho26-Dec-10 9:48 
GeneralRe: Problems Pin
regbnvl26-Dec-10 9:53
regbnvl26-Dec-10 9:53 
GeneralRe: Problems Pin
lipinho26-Dec-10 9:58
lipinho26-Dec-10 9:58 
GeneralRe: Problems Pin
Sacha Barber26-Dec-10 20:02
Sacha Barber26-Dec-10 20:02 
GeneralRe: Problems Pin
lipinho26-Dec-10 20:11
lipinho26-Dec-10 20:11 
GeneralRe: Problems Pin
Ryner Lute: T.L.D29-Apr-14 18:39
Ryner Lute: T.L.D29-Apr-14 18:39 
GeneralI think your article is misleading Pin
Sacha Barber25-Dec-10 22:11
Sacha Barber25-Dec-10 22:11 
GeneralRe: I think your article is misleading Pin
lipinho26-Dec-10 9:52
lipinho26-Dec-10 9:52 
GeneralRe: I think your article is misleading Pin
Manuel Quelhas27-Dec-10 2:07
Manuel Quelhas27-Dec-10 2:07 
GeneralMy vote of 5 Pin
RaviRanjanKr25-Dec-10 18:18
professionalRaviRanjanKr25-Dec-10 18:18 
GeneralRe: My vote of 5 Pin
lipinho25-Dec-10 18:19
lipinho25-Dec-10 18:19 
GeneralRe: My vote of 5 Pin
RaviRanjanKr25-Dec-10 18:50
professionalRaviRanjanKr25-Dec-10 18:50 
GeneralMy vote of 5 Pin
User 246299124-Dec-10 3:57
professionalUser 246299124-Dec-10 3:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.