Click here to Skip to main content
15,891,902 members
Articles / Programming Languages / C#

Is the Ready Queue FIFO?

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
26 Jul 2009CPOL5 min read 37.6K   814   14  
The Truth and the Proof.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Drawing;
using System.Runtime.Serialization;

namespace Common
{
	internal enum GW : uint
	{
		HWNDFIRST = 0,
		HWNDLAST = 1,
		HWNDNEXT = 2,
		HWNDPREV = 3,
		OWNER = 4,
		CHILD = 5,
		ENABLEDPOPUP = 6,
	}

	internal enum GWL : int
	{
		WNDPROC = -4,
		HINSTANCE = -6,
		HWNDPARENT = -8,
		STYLE = -16,
		EXSTYLE = -20,
		USERDATA = -21,
		ID = -12,
	}

	internal class ICON
	{
		public const UInt32 SMALL = 0;
		public const UInt32 BIG = 1;
		public const UInt32 SMALL2 = 2; // XP+
	}

	internal enum MB : uint
	{
		SimpleBeep = 0xFFFFFFFF,
		IconAsterisk = 0x00000040,
		IconWarning = 0x00000030,
		IconError = 0x00000010,
		IconQuestion = 0x00000020,
		OK = 0x00000000
	}

	[Flags]
	internal enum RDW : uint
	{
		INVALIDATE = 0x0001,
		INTERNALPAINT = 0x0002,
		ERASE = 0x0004,
		VALIDATE = 0x0008,
		NOINTERNALPAINT = 0x0010,
		NOERASE = 0x0020,
		NOCHILDREN = 0x0040,
		ALLCHILDREN = 0x0080,
		UPDATENOW = 0x0100,
		ERASENOW = 0x0200,
		FRAME = 0x0400,
		NOFRAME = 0x0800,
	}

	internal class SW
	{
		public const int HIDE = 0;
		public const int SHOWNORMAL = 1;
		public const int NORMAL = 1;
		public const int SHOWMINIMIZED = 2;
		public const int SHOWMAXIMIZED = 3;
		public const int MAXIMIZE = 3;
		public const int SHOWNOACTIVATE = 4;
		public const int SHOW = 5;
		public const int MINIMIZE = 6;
		public const int SHOWMINNOACTIVE = 7;
		public const int SHOWNA = 8;
		public const int RESTORE = 9;
		public const int SHOWDEFAULT = 10;
		public const int FORCEMINIMIZE = 11;
		public const int MAX = 11;
	}

	[Flags]
	internal enum CS : uint
	{
		VREDRAW = 0x0001,
		HREDRAW = 0x0002,
		DBLCLKS = 0x0008,
		OWNDC = 0x0020,
		CLASSDC = 0x0040,
		PARENTDC = 0x0080,
		NOCLOSE = 0x0200,
		SAVEBITS = 0x0800,
		BYTEALIGNCLIENT = 0x1000,
		BYTEALIGNWINDOW = 0x2000,
		GLOBALCLASS = 0x4000,

		IME = 0x00010000,
		DROPSHADOW = 0x00020000,
	}

	internal class TB
	{
		public const uint SETSTATE = WM.USER + 17;
		public const uint GETSTATE = WM.USER + 18;
		public const uint INSERTBUTTONA = WM.USER + 21;
		public const uint DELETEBUTTON = WM.USER + 22;
		public const uint GETBUTTON = WM.USER + 23;
		public const uint BUTTONCOUNT = WM.USER + 24;
		public const uint COMMANDTOINDEX = WM.USER + 25;
		public const uint CUSTOMIZE = WM.USER + 27;
		public const uint GETITEMRECT = WM.USER + 29;
		public const uint AUTOSIZE = WM.USER + 33;
		public const uint GETBUTTONTEXTA = WM.USER + 45;
		public const uint GETIMAGELIST = WM.USER + 49;
		public const uint GETBUTTONSIZE = WM.USER + 58;
		public const uint SETBUTTONWIDTH = WM.USER + 59;
		public const uint GETBUTTONINFOW = WM.USER + 63;
		public const uint SETBUTTONINFOW = WM.USER + 64;
		public const uint INSERTBUTTONW = WM.USER + 67;
		public const uint GETBUTTONTEXTW = WM.USER + 75;
		public const uint MOVEBUTTON = WM.USER + 82;
		public const uint GETMETRICS = WM.USER + 101;
	}

	// TBBUTTONINFO mask
	[Flags]
	internal enum TBIF : uint
	{
		IMAGE = 0x00000001,
		TEXT = 0x00000002,
		STATE = 0x00000004,
		STYLE = 0x00000008,
		LPARAM = 0x00000010,
		COMMAND = 0x00000020,
		SIZE = 0x00000040,
		BYINDEX = 0x80000000,
	}

	//internal class TBSTATE
	//{
	//    public const uint CHECKED = 0x01;
	//    public const uint PRESSED = 0x02;
	//    public const uint ENABLED = 0x04;
	//    public const uint HIDDEN = 0x08;
	//    public const uint INDETERMINATE = 0x10;
	//    public const uint WRAP = 0x20;
	//    public const uint ELLIPSES = 0x40;
	//    public const uint MARKED = 0x80;
	//}

	[Flags]
	internal enum TBSTATE : byte
	{
		CHECKED = 0x01,
		PRESSED = 0x02,
		ENABLED = 0x04,
		HIDDEN = 0x08,
		INDETERMINATE = 0x10,
		WRAP = 0x20,
		ELLIPSES = 0x40,
		MARKED = 0x80,
	}
	internal class PM
	{
		public const uint NOREMOVE = 0x0000;
		public const uint REMOVE = 0x0001;
		public const uint NOYIELD = 0x0002;
	}

	internal class WM
	{
		public const uint PAINT = 0x000F;
		public const uint CLOSE = 0x0010;
		public const uint SETTINGCHANGE = 0x001A;
		public const uint GETICON = 0x007F;
		public const uint KEYDOWN = 0x0100;
		public const uint COMMAND = 0x0111;
		public const uint HSCROLL = 0x114;
		public const uint VSCROLL = 0x115;
		public const uint HOTKEY = 0x312;
		public const uint USER = 0x0400; // 0x0400 - 0x7FFF
		public const uint APP = 0x8000; // 0x8000 - 0xBFFF

		public const uint MOUSEMOVE = 0x0200;
		public const uint LBUTTONDOWN = 0x0201;
		public const uint LBUTTONUP = 0x0202;
		public const uint LBUTTONDBLCLK = 0x0203;
	}

	[Flags]
	internal enum MOD : uint
	{
		ALT = 0x1,
		CONTROL = 0x2,
		SHIFT = 0x4,
		WIN = 0x8,
	}

	[Flags]
	internal enum WS : uint
	{
		OVERLAPPED = 0x00000000,
		POPUP = 0x80000000,
		CHILD = 0x40000000,
		MINIMIZE = 0x20000000,
		VISIBLE = 0x10000000,
		DISABLED = 0x08000000,
		CLIPSIBLINGS = 0x04000000,
		CLIPCHILDREN = 0x02000000,
		MAXIMIZE = 0x01000000,
		CAPTION = 0x00C00000,    /* WS_BORDER | WS_DLGFRAME  */
		BORDER = 0x00800000,
		DLGFRAME = 0x00400000,
		VSCROLL = 0x00200000,
		HSCROLL = 0x00100000,
		SYSMENU = 0x00080000,
		THICKFRAME = 0x00040000,
		GROUP = 0x00020000,
		TABSTOP = 0x00010000,

		MINIMIZEBOX = 0x00020000,
		MAXIMIZEBOX = 0x00010000,

		TILED = OVERLAPPED,
		ICONIC = MINIMIZE,
		SIZEBOX = THICKFRAME,
		TILEDWINDOW = OVERLAPPEDWINDOW,

		OVERLAPPEDWINDOW = ( OVERLAPPED |
							 CAPTION |
							 SYSMENU |
							 THICKFRAME |
							 MINIMIZEBOX |
							 MAXIMIZEBOX ),

		POPUPWINDOW = ( POPUP |
							 BORDER |
							 SYSMENU ),

		CHILDWINDOW = ( CHILD ),
	}

	[Flags]
	internal enum WSEX : uint
	{
		DLGMODALFRAME = 0x00000001,
		NOPARENTNOTIFY = 0x00000004,
		TOPMOST = 0x00000008,
		ACCEPTFILES = 0x00000010,
		TRANSPARENT = 0x00000020,

		MDICHILD = 0x00000040,
		TOOLWINDOW = 0x00000080,
		WINDOWEDGE = 0x00000100,
		CLIENTEDGE = 0x00000200,
		CONTEXTHELP = 0x00000400,

		RIGHT = 0x00001000,
		LEFT = 0x00000000,
		RTLREADING = 0x00002000,
		LTRREADING = 0x00000000,
		LEFTSCROLLBAR = 0x00004000,
		RIGHTSCROLLBAR = 0x00000000,

		CONTROLPARENT = 0x00010000,
		STATICEDGE = 0x00020000,
		APPWINDOW = 0x00040000,

		OVERLAPPEDWINDOW = ( WINDOWEDGE | CLIENTEDGE ),
		PALETTEWINDOW = ( WINDOWEDGE | TOOLWINDOW | TOPMOST ),

		LAYERED = 0x00080000,

		NOINHERITLAYOUT = 0x00100000, // Disable inheritence of mirroring by children
		LAYOUTRTL = 0x00400000, // Right to left mirroring

		COMPOSITED = 0x02000000,

		NOACTIVATE = 0x08000000,
	}

	internal class GCL
	{
		public const int MENUNAME = -8;
		public const int HBRBACKGROUND = -10;
		public const int HCURSOR = -12;
		public const int HICON = -14;
		public const int HMODULE = -16;
		public const int CBWNDEXTRA = -18;
		public const int CBCLSEXTRA = -20;
		public const int WNDPROC = -24;
		public const int STYLE = -26;
		public const int ATOM = -32;
		public const int HICONSM = -34;

		// GetClassLongPtr ( 64-bit )
		private const int GCW_ATOM = -32;
		private const int GCL_CBCLSEXTRA = -20;
		private const int GCL_CBWNDEXTRA = -18;
		private const int GCLP_MENUNAME = -8;
		private const int GCLP_HBRBACKGROUND = -10;
		private const int GCLP_HCURSOR = -12;
		private const int GCLP_HICON = -14;
		private const int GCLP_HMODULE = -16;
		private const int GCLP_WNDPROC = -24;
		private const int GCLP_HICONSM = -34;
		private const int GCL_STYLE = -26;

	}

	internal class INPUT
	{
		public const int MOUSE = 0;
		public const int KEYBOARD = 1;
		public const int HARDWARE = 2;
	}

	internal class MOUSEEVENTF
	{
		public const int MOVE = 0x0001; /* mouse move */
		public const int LEFTDOWN = 0x0002; /* left button down */
		public const int LEFTUP = 0x0004; /* left button up */
		public const int RIGHTDOWN = 0x0008; /* right button down */
		public const int RIGHTUP = 0x0010; /* right button up */
		public const int MIDDLEDOWN = 0x0020; /* middle button down */
		public const int MIDDLEUP = 0x0040; /* middle button up */
		public const int XDOWN = 0x0080; /* x button down */
		public const int XUP = 0x0100; /* x button down */
		public const int WHEEL = 0x0800; /* wheel button rolled */
		public const int VIRTUALDESK = 0x4000; /* map to entire virtual desktop */
		public const int ABSOLUTE = 0x8000; /* absolute move */
	}

	[StructLayout( LayoutKind.Sequential )]
	internal struct POINT
	{
		public Int32 X;
		public Int32 Y;
	}

	[StructLayout( LayoutKind.Sequential )]
	public struct RECT
	{
		public Int32 Left;
		public Int32 Top;
		public Int32 Right;
		public Int32 Bottom;

		public RECT( int left, int top, int right, int bottom )
		{
			Left = left;
			Top = top;
			Right = right;
			Bottom = bottom;
		}

		public override int GetHashCode()
		{
			return Left ^ ( ( Top << 13 ) | ( Top >> 0x13 ) )
			  ^ ( ( Width << 0x1a ) | ( Width >> 6 ) )
			  ^ ( ( Height << 7 ) | ( Height >> 0x19 ) );
		}

		public Int32 Width { get { return Right - Left; } }
		public Int32 Height { get { return Bottom - Top; } }

		public Rectangle ToRectangle() { return Rectangle.FromLTRB( Left, Top, Right, Bottom ); }
		public static RECT FromRectangle( Rectangle rectangle ) { return new RECT( rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Bottom ); }

		public static implicit operator Rectangle( RECT rect ) { return rect.ToRectangle(); }
		public static implicit operator RECT( Rectangle rect ) { return FromRectangle( rect ); }

	}

	// different structure definition for x86 and x64
	[StructLayout( LayoutKind.Explicit, Pack = 1 )]
	[Serializable]
	public struct TBBUTTON : ISerializable
	{
		[FieldOffset( 0 )]
		public Int32 iBitmap;
		[FieldOffset( 4 )]
		public Int32 idCommand;
		[FieldOffset( 8 )]
		public byte fsState;
		[FieldOffset( 9 )]
		public byte fsStyle;
		[FieldOffset( 10 )]
		public byte bReserved1;
		[FieldOffset( 11 )]
		public byte bReserved2;

		// x64 only
		[FieldOffset( 12 )]
		public byte bReserved3;
		[FieldOffset( 13 )]
		public byte bReserved4;
		[FieldOffset( 14 )]
		public byte bReserved5;
		[FieldOffset( 15 )]
		public byte bReserved6;

		// x86
		[FieldOffset( 12 )]
		public Int32 dwData32;
		[FieldOffset( 16 )]
		public Int32 iString32;

		// x64
		[FieldOffset( 16 )]
		public Int64 dwData64;
		[FieldOffset( 24 )]
		public Int64 iString64;

		public IntPtr dwData
		{
			get { return new IntPtr( IntPtr.Size == 4 ? dwData32 : dwData64 ); }
			set { if ( IntPtr.Size == 4 ) dwData32 = value.ToInt32(); else dwData64 = value.ToInt64(); }
		}

		public IntPtr iString
		{
			get { return new IntPtr( IntPtr.Size == 4 ? iString32 : iString64 ); }
			set { if ( IntPtr.Size == 4 ) iString32 = value.ToInt32(); else iString64 = value.ToInt64(); }
		}

		#region ISerializable Members

		// save
		public void GetObjectData( SerializationInfo info, StreamingContext context )
		{
			info.AddValue( "DataBase.version", 1 );

			info.AddValue( "iBitmap", iBitmap );
			info.AddValue( "idCommand", idCommand );
			info.AddValue( "fsState", fsState );
			info.AddValue( "fsStyle", fsStyle );

			info.AddValue( "IntPtr.Size", IntPtr.Size );

			if ( IntPtr.Size == 4 )
			{
				info.AddValue( "dwData32", dwData32 );
				info.AddValue( "iString32", iString32 );
			}
			else
			{
				info.AddValue( "dwData64", dwData64 );
				info.AddValue( "iString64", iString64 );
			}
		}

		// load
		public TBBUTTON( SerializationInfo info, StreamingContext context )
			: this()
		{
			int version = info.GetInt32( "DataBase.version" );

			iBitmap = info.GetInt32( "iBitmap" );
			idCommand = info.GetInt32( "idCommand" );
			fsState = info.GetByte( "fsState" );
			fsStyle = info.GetByte( "fsStyle" );

			var intPtrSize = info.GetInt32( "IntPtr.Size" );

			if ( intPtrSize == 4 )
			{
				dwData32 = info.GetInt32( "dwData32" );
				iString32 = info.GetInt32( "iString32" );
			}
			else
			{
				dwData64 = info.GetInt64( "dwData64" );
				iString64 = info.GetInt64( "iString64" );
			}
		}

		#endregion
	}

	[StructLayout( LayoutKind.Sequential )]
	public struct TBBUTTONINFO
	{
		public int cbSize;
		public int dwMask;
		public int idCommand;
		public int iImage;
		public byte fsState;
		public byte fsStyle;
		public short cx;
		public IntPtr lParam;
		public IntPtr pszText;
		public int cchText;
	}

	[StructLayout( LayoutKind.Sequential )]
	internal struct WINDOWPLACEMENT
	{
		public int Length;
		public int Flags;
		public int ShowCmd;
		public POINT MinPosition;
		public POINT MaxPosition;
		public RECT NormalPosition;
	}

	[StructLayout( LayoutKind.Sequential )]
	internal struct MOUSEINPUT
	{
		public int dx;
		public int dy;
		public int mouseData;
		public int dwFlags;
		public int time;
		public IntPtr dwExtraInfo;
	}

	[StructLayout( LayoutKind.Sequential )]
	internal struct KEYBDINPUT
	{
		public short wVk;
		public short wScan;
		public int dwFlags;
		public int time;
		public IntPtr dwExtraInfo;
	}

	[StructLayout( LayoutKind.Sequential )]
	internal struct HARDWAREINPUT
	{
		public int uMsg;
		public short wParamL;
		public short wParamH;
	}

	[StructLayout( LayoutKind.Explicit )]
	internal struct Input
	{
		[FieldOffset( 0 )]
		public int type;
		[FieldOffset( 4 )]
		public MOUSEINPUT mi;
		[FieldOffset( 4 )]
		public KEYBDINPUT ki;
		[FieldOffset( 4 )]
		public HARDWAREINPUT hi;
	}

	[StructLayout( LayoutKind.Sequential )]
	public struct MSG
	{
		public IntPtr hwnd;
		public UInt32 message;
		public IntPtr wParam;
		public IntPtr lParam;
		public UInt32 time;
		internal POINT pt;
	}

	internal class User32
	{
		private User32() { }

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

		public static IntPtr SendMessage(
			IntPtr hWnd,
			UInt32 msg,
			Int32 wParam,
			Int32 lParam )
		{ return SendMessage( hWnd, msg, new IntPtr( wParam ), new IntPtr( lParam ) ); }

		public static IntPtr SendMessage(
			IntPtr hWnd,
			UInt32 msg,
			UInt32 wParam,
			UInt32 lParam )
		{ return SendMessage( hWnd, msg, new IntPtr( wParam ), new IntPtr( lParam ) ); }

		[DllImport( "User32.dll" )]
		public static extern bool PostMessage
		(
			IntPtr hWnd,
			UInt32 msg,
			IntPtr wParam,
			IntPtr lParam
		);

		public static bool PostMessage
		(
			IntPtr hWnd,
			UInt32 msg,
			Int32 wParam,
			Int32 lParam
		)
		{ return PostMessage( hWnd, msg, new IntPtr( wParam ), new IntPtr( lParam ) ); }

		public static bool PostMessage
		(
			IntPtr hWnd,
			UInt32 msg,
			UInt32 wParam,
			UInt32 lParam
		)
		{ return PostMessage( hWnd, msg, new IntPtr( wParam ), new IntPtr( lParam ) ); }

		[DllImport( "User32.dll" )]
		public static extern bool PeekMessage(
			out MSG msg,
			IntPtr hWnd,
			uint msgFilterMin,
			uint msgFilterMax,
			uint removeFlags );

		[DllImport( "User32.dll", SetLastError = true, CharSet = CharSet.Auto )]
		public static extern IntPtr SendMessageTimeout(
			IntPtr hWnd,
			uint Msg,
			IntPtr wParam,
			IntPtr lParam,
			uint flags,
			uint timeout,
			out IntPtr result );

		[DllImport( "User32.dll" )]
		public static extern bool MessageBeep
		(
			MB BeepType
		);

		[DllImport( "user32.dll" )]
		public static extern bool ShowWindow
		(
			IntPtr hWnd,
			int nCmdShow
		);

		[DllImport( "user32.dll" )]
		public static extern bool ShowWindow
		(
			HandleRef hWnd,
			int nCmdShow
		);

		[DllImport( "User32.dll" )]
		public static extern bool SetForegroundWindow
		(
			IntPtr hWnd
		);


		[DllImport( "User32.dll" )]
		public static extern IntPtr GetDesktopWindow
		(
		);

		[DllImport( "User32.dll" )]
		public static extern IntPtr GetTaskmanWindow
		(
		);

		[DllImport( "user32.dll", CharSet = CharSet.Unicode, SetLastError = true )]
		public static extern IntPtr FindWindow(
			string lpszClass,
			string lpszWindow );

		[DllImport( "user32.dll", CharSet = CharSet.Unicode )]
		public static extern IntPtr FindWindowEx(
			IntPtr hwndParent,
			IntPtr hwndChildAfter,
			string lpszClass,
			string lpszWindow );

		[DllImport( "User32.dll" )]
		public static extern IntPtr GetWindow
		(
			IntPtr hWnd,
			GW uCmd
		);

		[DllImport( "User32.dll" )]
		public static extern Int32 GetWindowTextLength
		(
			IntPtr hWnd
		);

		[DllImport( "User32.dll", SetLastError = true, CharSet = CharSet.Auto )]
		public static extern Int32 GetWindowText
		(
			IntPtr hWnd,
			StringBuilder lpString,
			Int32 nMaxCount
		);

		[DllImport( "User32.dll", CharSet = CharSet.Auto )]
		public static extern Int32 GetClassName
		(
			IntPtr hWnd,
			out StringBuilder lpClassName,
			Int32 nMaxCount
		);

		//		[ DllImport( "user32.dll", EntryPoint = "GetClassLongPtrW" ) ]
		[DllImport( "user32.dll" )]
		public static extern UInt32 GetClassLong
		(
			IntPtr hWnd,
			int nIndex
		);

		[DllImport( "user32.dll" )]
		public static extern uint SetClassLong
		(
			IntPtr hWnd,
			int nIndex,
			uint dwNewLong
		);

		[DllImport( "user32.dll" )]
		public static extern IntPtr GetWindowLongPtr( HandleRef hWnd, int nIndex );

		[DllImport( "user32.dll" )]
		public static extern IntPtr SetWindowLongPtr( HandleRef hWnd, int nIndex, IntPtr dwNewLong );

		[DllImport( "user32.dll" )]
		public static extern bool GetClientRect( IntPtr hWnd, out RECT lpRect );

		[DllImport( "user32.dll" )]
		public static extern bool ClientToScreen( IntPtr hWnd, ref POINT lpPoint );

		//[DllImport( "user32.dll", SetLastError = true )]
		//static extern uint GetWindowThreadProcessId
		//    (
		//    IntPtr hWnd,
		//    out UInt32 lpdwProcessId
		//    );

		[DllImport( "User32.dll", SetLastError = true )]
		public static extern UInt32 GetWindowThreadProcessId
		(
			IntPtr hWnd,
			//			[ MarshalAs( UnmanagedType.
			out UInt32 lpdwProcessId
		);

		[DllImport( "User32.dll" )]
		public static extern bool RedrawWindow
		(
			IntPtr hWnd,
			//			[In] ref RECT lprcUpdate,
			IntPtr lprcUpdate,
			IntPtr hrgnUpdate,
			uint flags
		);

		public static bool RedrawWindow( IntPtr hWnd )
		{
			return RedrawWindow( hWnd, IntPtr.Zero, IntPtr.Zero,
				( uint ) ( RDW.ERASE | RDW.INVALIDATE | RDW.UPDATENOW ) );
		}

		[DllImport( "User32.dll" )]
		public static extern UInt32 SendInput
		(
			UInt32 nInputs,
			Input[] pInputs,
			Int32 cbSize
		);

		[DllImport( "User32.dll" )]
		[return: MarshalAs( UnmanagedType.Bool )]
		public static extern bool RegisterHotKey( IntPtr hWnd, int id, MOD modifiers, int vk );

		[DllImport( "User32.dll" )]
		[return: MarshalAs( UnmanagedType.Bool )]
		public static extern bool UnregisterHotKey( IntPtr hWnd, int id );

		[DllImport( "User32.dll" )]
		public static extern bool GetWindowPlacement
		(
			IntPtr hWnd,
			ref WINDOWPLACEMENT lpwndpl
		);

		[DllImport( "User32.dll" )]
		public static extern IntPtr WindowFromPoint
		(
			POINT pt
		);

		[DllImport( "User32.dll" )]
		public static extern bool FlashWindow
		(
			IntPtr hWnd,
			bool bInvert
		);




	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
United Kingdom United Kingdom
I discovered C# and .NET 1.0 Beta 1 in late 2000 and loved them immediately.
I have been writing software professionally in C# ever since

In real life, I have spent 3 years travelling abroad,
I have held a UK Private Pilots Licence for 20 years,
and I am a PADI Divemaster.

I now live near idyllic Bournemouth in England.

I can work 'virtually' anywhere!

Comments and Discussions