Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C#

Themed Windows XP style Explorer Bar

Rate me:
Please Sign up or sign in to vote.
4.96/5 (471 votes)
6 Oct 200515 min read 1.9M   72.6K   1.1K  
A fully customizable Windows XP style Explorer Bar that supports Windows XP themes and animated expand/collapse with transparency.
/*
 * Copyright (c) 2004, Mathew Hall
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *    - Redistributions of source code must retain the above copyright notice, 
 *      this list of conditions and the following disclaimer.
 * 
 *    - Redistributions in binary form must reproduce the above copyright notice, 
 *      this list of conditions and the following disclaimer in the documentation 
 *      and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 * OF SUCH DAMAGE.
 */


using System;
using System.Runtime.InteropServices;
using System.Text;


namespace XPExplorerBar
{
	#region NativeMethods
	
	/// <summary>
	/// Summary description for NativeMethods.
	/// </summary>
	public abstract class NativeMethods
	{
		/// <summary>
		/// The LoadLibraryEx function maps the specified executable module into the 
		/// address space of the calling process. The executable module can be a .dll 
		/// or an .exe file. The specified module may cause other modules to be mapped 
		/// into the address space
		/// </summary>
		/// <param name="lpfFileName">A String that names the executable module (either 
		/// a .dll or an .exe file). The name specified is the file name of the executable 
		/// module. This name is not related to the name stored in a library module itself, 
		/// as specified by the LIBRARY keyword in the module-definition (.def) file. If 
		/// the string specifies a path, but the file does not exist in the specified 
		/// directory, the function fails. When specifying a path, be sure to use backslashes 
		/// (\), not forward slashes (/). If the string does not specify a path, and the file 
		/// name extension is omitted, the function appends the default library extension 
		/// .dll to the file name. However, the file name string can include a trailing point 
		/// character (.) to indicate that the module name has no extension. If the string 
		/// does not specify a path, the function uses a standard search strategy to find 
		/// the file. If mapping the specified module into the address space causes the system 
		/// to map in other, associated executable modules, the function can use either the 
		/// standard search strategy or an alternate search strategy to find those modules.</param>
		/// <param name="flags">Action to take when loading the module. If no flags are 
		/// specified, the behavior of this function is identical to that of the LoadLibrary 
		/// function. This parameter can be one of the LoadLibraryExFlags values</param>
		/// <returns>If the function succeeds, the return value is an IntPtr to the mapped 
		/// executable module. If the function fails, the return value is IntPtr.Zero.</returns>
		public static IntPtr LoadLibraryEx(string lpfFileName, LoadLibraryExFlags flags)
		{
			return NativeMethods.InternalLoadLibraryEx(lpfFileName, IntPtr.Zero, (int) flags);
		}

		[DllImport("Kernel32.dll", EntryPoint="LoadLibraryEx")]
		private static extern IntPtr InternalLoadLibraryEx(string lpfFileName, IntPtr hFile, int dwFlags);


		/// <summary>
		/// The FreeLibrary function decrements the reference count of the loaded 
		/// dynamic-link library (DLL). When the reference count reaches zero, the 
		/// module is unmapped from the address space of the calling process and the 
		/// handle is no longer valid
		/// </summary>
		/// <param name="hModule">An IntPtr that points to the loaded DLL module. 
		/// The LoadLibrary function returns this IntPtr</param>
		/// <returns>If the function succeeds, the return value is true. If the 
		/// function fails, the return value is false</returns>
		[DllImport("Kernel32.dll")]
		public static extern bool FreeLibrary(IntPtr hModule);
		
		
		/// <summary>
		/// The FindResource function determines the location of a resource with the 
		/// specified type and name in the specified module
		/// </summary>
		/// <param name="hModule">An IntPtr that points to the module whose executable 
		/// file contains the resource. A value of IntPtr.Zero specifies the module handle 
		/// associated with the image file that the operating system used to create the 
		/// current process</param>
		/// <param name="lpName">A String that specifies the name of the resource</param>
		/// <param name="lpType">An int that specifies the resource type</param>
		/// <returns>If the function succeeds, the return value is an IntPtr that points 
		/// to the specified resource's information block. To obtain an IntPtr that points 
		/// to the resource, pass this IntPtr to the LoadResource function. If the function 
		/// fails, the return value is IntPtr.Zero</returns>
		[DllImport( "Kernel32.dll" )]
		public static extern IntPtr FindResource(IntPtr hModule, string lpName, int lpType);

		/// <summary>
		/// The FindResource function determines the location of a resource with the 
		/// specified type and name in the specified module
		/// </summary>
		/// <param name="hModule">An IntPtr that points to the module whose executable 
		/// file contains the resource. A value of IntPtr.Zero specifies the module handle 
		/// associated with the image file that the operating system used to create the 
		/// current process</param>
		/// <param name="lpName">A String that specifies the name of the resource</param>
		/// <param name="lpType">A String that specifies the resource type</param>
		/// <returns>If the function succeeds, the return value is an IntPtr that points 
		/// to the specified resource's information block. To obtain an IntPtr that points 
		/// to the resource, pass this IntPtr to the LoadResource function. If the function 
		/// fails, the return value is IntPtr.Zero</returns>
		[DllImport( "Kernel32.dll" )]
		public static extern IntPtr FindResource(IntPtr hModule, string lpName, string lpType);


		/// <summary>
		/// The SizeofResource function returns the size, in bytes, of the specified 
		/// resource
		/// </summary>
		/// <param name="hModule">An IntPtr that points to the module whose executable 
		/// file contains the resource</param>
		/// <param name="hResInfo">An IntPtr that points to the resource. This IntPtr 
		/// must be created by using the FindResource function</param>
		/// <returns>If the function succeeds, the return value is the number of bytes 
		/// in the resource. If the function fails, the return value is zero</returns>
		[DllImport("Kernel32.dll")]
		public static extern int SizeofResource(IntPtr hModule, IntPtr hResInfo);


		/// <summary>
		/// The LoadResource function loads the specified resource into global memory
		/// </summary>
		/// <param name="hModule">An IntPtr that points to the module whose executable 
		/// file contains the resource. If the value of hModule is IntPtr.Zero, the system 
		/// loads the resource from the module that was used to create the current process</param>
		/// <param name="hResInfo">An IntPtr that points to the resource to be loaded. 
		/// This IntPtr is returned by the FindResource function</param>
		/// <returns>If the function succeeds, the return value is an IntPtr that points 
		/// to the data associated with the resource. If the function fails, the return 
		/// value is IntPtr.Zero</returns>
		[DllImport("Kernel32.dll")]
		public static extern System.IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);


		/// <summary>
		/// The FreeResource function decrements (decreases by one) the reference count 
		/// of a loaded resource. When the reference count reaches zero, the memory occupied 
		/// by the resource is freed
		/// </summary>
		/// <param name="hglbResource">An IntPtr that points to the resource. It is assumed 
		/// that hglbResource was created by LoadResource</param>
		/// <returns>If the function succeeds, the return value is zero. If the function fails, 
		/// the return value is non-zero, which indicates that the resource has not been freed</returns>
		[DllImport("Kernel32.dll")] 
		public static extern int FreeResource(IntPtr hglbResource);


		/// <summary>
		/// The CopyMemory function copies a block of memory from one location to another
		/// </summary>
		/// <param name="Destination">An IntPtr that points to the starting address of 
		/// the copied block's destination</param>
		/// <param name="Source">An IntPtr that points to the starting address of the block 
		/// of memory to copy</param>
		/// <param name="Length">Size of the block of memory to copy, in bytes</param>
		[DllImport("Kernel32.dll")] 
		public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);


		/// <summary>
		/// The LoadBitmap function loads the specified bitmap resource from a module's 
		/// executable file
		/// </summary>
		/// <param name="hInstance">An IntPtr that points to the instance of the module 
		/// whose executable file contains the bitmap to be loaded</param>
		/// <param name="lpBitmapName">An IntPtr that points to a null-terminated string 
		/// that contains the name of the bitmap resource to be loaded. Alternatively, 
		/// this parameter can consist of the resource identifier in the low-order word and 
		/// zero in the high-order word</param>
		/// <returns>If the function succeeds, the return value is an IntPtr that points 
		/// to the specified bitmap. If the function fails, the return value is IntPtr.Zero</returns>
		[DllImport("User32.dll")]
		public static extern IntPtr LoadBitmap(IntPtr hInstance, long lpBitmapName);


		/// <summary>
		/// The GdiFlush function flushes the calling thread's current batch
		/// </summary>
		/// <returns>If all functions in the current batch succeed, the return value is 
		/// nonzero. If not all functions in the current batch succeed, the return value 
		/// is zero, indicating that at least one function returned an error</returns>
		[DllImport("Gdi32.dll")] 
		public static extern int GdiFlush();


		/// <summary>
		/// The LoadString function loads a string resource from the executable file 
		/// associated with a specified module, copies the string into a buffer, and 
		/// appends a terminating null character
		/// </summary>
		/// <param name="hInstance">An IntPtr that points to an instance of the module 
		/// whose executable file contains the string resource</param>
		/// <param name="uID">Specifies the integer identifier of the string to be loaded</param>
		/// <param name="lpBuffer">An IntPtr that points to the buffer to receive the string</param>
		/// <param name="nBufferMax">Specifies the size of the buffer, in TCHARs. This 
		/// refers to bytes for versions of the function or WCHARs for Unicode versions. 
		/// The string is truncated and null terminated if it is longer than the number 
		/// of characters specified</param>
		/// <returns>If the function succeeds, the return value is the number of TCHARs 
		/// copied into the buffer, not including the null-terminating character, or 
		/// zero if the string resource does not exist</returns>
		[DllImport("User32.dll")]
		public static extern int LoadString(IntPtr hInstance, int uID, StringBuilder lpBuffer, int nBufferMax);


		/// <summary>
		/// The SendMessage function sends the specified message to a window or windows. 
		/// It calls the window procedure for the specified window and does not return 
		/// until the window procedure has processed the message
		/// </summary>
		/// <param name="hwnd">An IntPtr that points to the window whose window procedure 
		/// will receive the message</param>
		/// <param name="msg">An int that specifies the message to be sent</param>
		/// <param name="wParam">An IntPtr that specifies additional message-specific 
		/// information</param>
		/// <param name="lParam">An IntPtr that specifies additional message-specific 
		/// information</param>
		/// <returns>The return value specifies the result of the message processing; 
		/// it depends on the message sent</returns>
		public static int SendMessage(IntPtr hwnd, WindowMessageFlags msg, IntPtr wParam, IntPtr lParam)
		{
			return NativeMethods.InternalSendMessage(hwnd, (int) msg, wParam, lParam);
		}

		[DllImport("User32.dll", EntryPoint="SendMessage")] 
		private static extern int InternalSendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);


		/// <summary>
		/// Implemented by many of the Microsoft� Windows� Shell dynamic-link libraries 
		/// (DLLs) to allow applications to obtain DLL-specific version information
		/// </summary>
		/// <param name="pdvi">Pointer to a DLLVERSIONINFO structure that receives the 
		/// version information. The cbSize member must be filled in before calling 
		/// the function</param>
		/// <returns>Returns NOERROR if successful, or an OLE-defined error value otherwise</returns>
		[DllImport("Comctl32.dll")] 
		public static extern int DllGetVersion(ref DLLVERSIONINFO pdvi);


		/// <summary>
		/// The GetProcAddress function retrieves the address of an exported function 
		/// or variable from the specified dynamic-link library (DLL)
		/// </summary>
		/// <param name="hModule">An IntPtr that points to the DLL module that contains 
		/// the function or variable. The LoadLibrary function returns this IntPtr</param>
		/// <param name="procName">A String that specifies the function or variable name, 
		/// or the function's ordinal value. If this parameter is an ordinal value, it 
		/// must be in the low-order word; the high-order word must be zero</param>
		/// <returns>If the function succeeds, the return value is aAn IntPtr that points 
		/// to the address of the exported function or variable. If the function fails, the 
		/// return value is IntPtr.Zero</returns>
		[DllImport("Kernel32.dll", CharSet=CharSet.Ansi, ExactSpelling=true)]
		public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);


		/// <summary>
		/// The SetErrorMode function controls whether the system will handle the 
		/// specified types of serious errors, or whether the process will handle them
		/// </summary>
		/// <param name="uMode">Process error mode. This parameter can be one or more of 
		/// the SetErrorModeFlags values</param>
		/// <returns>The return value is the previous state of the error-mode bit flags</returns>
		public static int SetErrorMode(SetErrorModeFlags uMode)
		{
			return NativeMethods.InternalSetErrorMode((int) uMode);
		}

		[DllImport("Kernel32.dll", EntryPoint="SetErrorMode")] 
		private static extern int InternalSetErrorMode(int uMode);


		/// <summary>
		/// The GetWindowDC function retrieves the device context (DC) for the entire 
		/// window, including title bar, menus, and scroll bars. A window device context 
		/// permits painting anywhere in a window, because the origin of the device 
		/// context is the upper-left corner of the window instead of the client area
		/// </summary>
		/// <param name="hwnd">An IntPtr that points to the window with a device context 
		/// that is to be retrieved. If this value is IntPtr.Zero, GetWindowDC retrieves 
		/// the device context for the entire screen</param>
		/// <returns>If the function succeeds, the return value is an IntPtr that points 
		/// to a device context for the specified window. If the function fails, the return 
		/// value is IntPtr.Zero, indicating an error or an invalid hWnd parameter</returns>
		[DllImport("User32.dll")] 
		public static extern IntPtr GetWindowDC(IntPtr hwnd);


		/// <summary>
		/// The ReleaseDC function releases a device context (DC), freeing it for use 
		/// by other applications. The effect of the ReleaseDC function depends on the 
		/// type of DC. It frees only common and window DCs. It has no effect on class 
		/// or private DCs
		/// </summary>
		/// <param name="hwnd">An IntPtr that points to the window whose DC is to be 
		/// released</param>
		/// <param name="hdc">An IntPtr that points to the DC to be released</param>
		/// <returns>The return value indicates whether the DC was released. If the DC 
		/// was released, the return value is 1. If the DC was not released, the return 
		/// value is zero</returns>
		[DllImport("User32.dll")] 
		public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);


		/// <summary>
		/// The SetWindowPos function changes the size, position, and Z order of a child, 
		/// pop-up, or top-level window. Child, pop-up, and top-level windows are ordered 
		/// according to their appearance on the screen. The topmost window receives the 
		/// highest rank and is the first window in the Z order
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to the window</param>
		/// <param name="hWndInsertAfter">An IntPtr that points to the window to precede 
		/// the positioned window in the Z order</param>
		/// <param name="X">Specifies the new position of the left side of the window, in 
		/// client coordinates</param>
		/// <param name="Y">Specifies the new position of the top of the window, in client 
		/// coordinates</param>
		/// <param name="cx">Specifies the new width of the window, in pixels</param>
		/// <param name="cy">Specifies the new height of the window, in pixels</param>
		/// <param name="uFlags">Specifies the window sizing and positioning flags. This 
		/// parameter can be a combination of the SetWindowPosFlags values</param>
		/// <returns>If the function succeeds, the return value is nonzero. If the function 
		/// fails, the return value is zero</returns>
		public static int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags)
		{
			return InternalSetWindowPos(hWnd, hWndInsertAfter, X, Y, cx, cy, (int) uFlags);
		}

		[DllImport("User32.dll", EntryPoint="SetWindowPos")] 
		private static extern int InternalSetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);


		/// <summary>
		/// The RedrawWindow function updates the specified rectangle or region in 
		/// a window's client area
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to the window to be redrawn. 
		/// If this parameter is IntPtr.Zero, the desktop window is updated</param>
		/// <param name="lprcUpdate">An IntPtr that points to a RECT structure containing 
		/// the coordinates, in device units, of the update rectangle. This parameter is 
		/// ignored if the hrgnUpdate parameter identifies a region</param>
		/// <param name="hrgnUpdate">An IntPtr that points to the update region. If both 
		/// the hrgnUpdate and lprcUpdate parameters are IntPtr.Zero, the entire client 
		/// area is added to the update region</param>
		/// <param name="flags">Specifies one or more redraw flags. This parameter can 
		/// be used to invalidate or validate a window, control repainting, and control 
		/// which windows are affected by RedrawWindow</param>
		/// <returns>If the function succeeds, the return value is nonzero. If the 
		/// function fails, the return value is zero</returns>
		public static bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags)
		{
			return InternalRedrawWindow(hWnd, lprcUpdate, hrgnUpdate, (int) flags);
		}
		
		[DllImport("User32.dll", EntryPoint="RedrawWindow")] 
		private static extern bool InternalRedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, int flags);


		/// <summary>
		/// The ShowScrollBar function shows or hides the specified scroll bar
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to a scroll bar control or a window with 
		/// a standard scroll bar, depending on the value of the wBar parameter</param>
		/// <param name="wBar">Specifies the scroll bar(s) to be shown or hidden. This 
		/// parameter can be one of the ScrollBarConstants values</param>
		/// <param name="bShow">Specifies whether the scroll bar is shown or hidden. If 
		/// this parameter is TRUE, the scroll bar is shown; otherwise, it is hidden</param>
		/// <returns>If the function succeeds, the return value is nonzero. If the function 
		/// fails, the return value is zero</returns>
		public static bool ShowScrollBar(IntPtr hWnd, ScrollBarConstants wBar, bool bShow)
		{
			return InternalShowScrollBar(hWnd, (int) wBar, bShow);
		}

		[DllImport("User32.dll", EntryPoint="ShowScrollBar")]
		private static extern bool InternalShowScrollBar(IntPtr hWnd, int wBar, bool bShow);


		/// <summary>
		/// The EnableScrollBar function enables or disables one or both scroll 
		/// bar arrows
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to a window or a scroll bar control, 
		/// depending on the value of the wSBflags parameter</param>
		/// <param name="wBar">Specifies the scroll bar type. This parameter can be 
		/// one of the ScrollBarConstants values</param>
		/// <param name="wArrows">Specifies whether the scroll bar arrows are enabled 
		/// or disabled and indicates which arrows are enabled or disabled. This 
		/// parameter can be one of the EnableScrollBarFlags values</param>
		/// <returns>If the arrows are enabled or disabled as specified, the return 
		/// value is nonzero. If the arrows are already in the requested state or an 
		/// error occurs, the return value is zero</returns>
		public static bool EnableScrollBar(IntPtr hWnd, ScrollBarConstants wBar, EnableScrollBarFlags wArrows)
		{
			return InternalEnableScrollBar(hWnd, (int) wBar, (int) wArrows);
		}

		[DllImport("User32.dll", EntryPoint="EnableScrollBar")]
		private static extern bool InternalEnableScrollBar(IntPtr hWnd, int wBar, int wArrows);


		/// <summary>
		/// The GetScrollInfo function retrieves the parameters of a scroll bar, including 
		/// the minimum and maximum scrolling positions, the page size, and the position 
		/// of the scroll box (thumb)
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to a scroll bar control or a window 
		/// with a standard scroll bar, depending on the value of the fnBar parameter</param>
		/// <param name="fnBar">Specifies the type of scroll bar for which to retrieve 
		/// parameters. This parameter can be one of the ScrollBarConstants values</param>
		/// <param name="lpsi">Reference to a SCROLLINFO structure. Before calling 
		/// GetScrollInfo, set the cbSize member to sizeof(SCROLLINFO), and set the fMask member 
		/// to specify the scroll bar parameters to retrieve. Before returning, the function copies 
		/// the specified parameters to the appropriate members of the structure. The fMask member 
		/// can be one or more of the ScrollInfoFlags values</param>
		/// <returns>If the function retrieved any values, the return value is nonzero. If 
		/// the function does not retrieve any values, the return value is zero</returns>
		public static bool GetScrollInfo(IntPtr hWnd, ScrollBarConstants fnBar, ref SCROLLINFO lpsi)
		{
			return InternalGetScrollInfo(hWnd, (int) fnBar, ref lpsi);
		}

		[DllImport("User32.dll", EntryPoint="GetScrollInfo")]
		private static extern bool InternalGetScrollInfo(IntPtr hWnd, int fnBar, ref SCROLLINFO lpsi);


		/// <summary>
		/// The GetScrollPos function retrieves the current position of the scroll box (thumb) 
		/// in the specified scroll bar. The current position is a relative value that depends 
		/// on the current scrolling range. For example, if the scrolling range is 0 through 
		/// 100 and the scroll box is in the middle of the bar, the current position is 50
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to a scroll bar control or a window with 
		/// a standard scroll bar, depending on the value of the nBar parameter</param>
		/// <param name="nBar">Specifies the scroll bar to be examined. This parameter can 
		/// be one of the ScrollBarConstants values</param>
		/// <returns>If the function succeeds, the return value is the current position of the 
		/// scroll box. If the function fails, the return value is zero</returns>
		[DllImport("User32.dll")]
		public static extern int GetScrollPos(IntPtr hWnd, int nBar);


		/// <summary>
		/// The SetScrollInfo function sets the parameters of a scroll bar, including the 
		/// minimum and maximum scrolling positions, the page size, and the position of the 
		/// scroll box (thumb). The function also redraws the scroll bar, if requested
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to a scroll bar control or a window with 
		/// a standard scroll bar, depending on the value of the fnBar parameter</param>
		/// <param name="fnBar">Specifies the type of scroll bar for which to set parameters. 
		/// This parameter can be one of the ScrollBarConstants values</param>
		/// <param name="lpsi">Reference to a SCROLLINFO structure. Before calling SetScrollInfo, 
		/// set the cbSize member of the structure to sizeof(SCROLLINFO), set the fMask member 
		/// to indicate the parameters to set, and specify the new parameter values in the 
		/// appropriate members. The fMask member can be one or more of the ScrollInfoFlags 
		/// values</param>
		/// <param name="fRedraw">Specifies whether the scroll bar is redrawn to reflect the 
		/// changes to the scroll bar. If this parameter is TRUE, the scroll bar is redrawn, 
		/// otherwise, it is not redrawn</param>
		/// <returns>The return value is the current position of the scroll box</returns>
		public static int SetScrollInfo(IntPtr hWnd, ScrollBarConstants fnBar, ref SCROLLINFO lpsi, bool fRedraw)
		{
			return InternalSetScrollInfo(hWnd, (int) fnBar, ref lpsi, fRedraw);
		}

		[DllImport("User32.dll", EntryPoint="SetScrollInfo")]
		private static extern int InternalSetScrollInfo(IntPtr hWnd, int fnBar, ref SCROLLINFO lpsi, bool fRedraw);


		/// <summary>
		/// The SetScrollPos function sets the position of the scroll box (thumb) in the 
		/// specified scroll bar and, if requested, redraws the scroll bar to reflect the 
		/// new position of the scroll box
		/// </summary>
		/// <param name="hWnd">An IntPtr that points to a scroll bar control or a window 
		/// with a standard scroll bar, depending on the value of the nBar parameter</param>
		/// <param name="nBar">Specifies the scroll bar to be set. This parameter can be 
		/// one of the ScrollBarConstants values</param>
		/// <param name="nPos">Specifies the new position of the scroll box. The position 
		/// must be within the scrolling range</param>
		/// <param name="bRedraw">Specifies whether the scroll bar is redrawn to reflect 
		/// the new scroll box position. If this parameter is TRUE, the scroll bar is 
		/// redrawn. If it is FALSE, the scroll bar is not redrawn</param>
		/// <returns>If the function succeeds, the return value is the previous position 
		/// of the scroll box. If the function fails, the return value is zero</returns>
		[DllImport("User32.dll")]
		public static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw);


		/// <summary>
		/// 
		/// </summary>
		/// <param name="n"></param>
		/// <returns></returns>
		public static int HIWORD(int n)
		{
			return ((n >> 16) & 65535);
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="n"></param>
		/// <returns></returns>
		public static int LOWORD(int n)
		{
			return (n & 65535);
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="low"></param>
		/// <param name="high"></param>
		/// <returns></returns>
		public static IntPtr MAKELPARAM(int low, int high)
		{
			return ((IntPtr) ((high << 0x10) | (low & 0xffff)));
		}
	}

	#endregion



	#region Structs

	/// <summary>
	/// The POINT structure defines the x- and y- coordinates of a point
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct POINT
	{
		/// <summary>
		/// Specifies the x-coordinate of the point
		/// </summary>
		public int x;
			
		/// <summary>
		/// Specifies the y-coordinate of the point
		/// </summary>
		public int y;
	}


	/// <summary>
	/// The RECT structure defines the coordinates of the upper-left 
	/// and lower-right corners of a rectangle
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct RECT
	{
		/// <summary>
		/// Specifies the x-coordinate of the upper-left corner of the rectangle
		/// </summary>
		public int left;
			
		/// <summary>
		/// Specifies the y-coordinate of the upper-left corner of the rectangle
		/// </summary>
		public int top;
			
		/// <summary>
		/// Specifies the x-coordinate of the lower-right corner of the rectangle
		/// </summary>
		public int right;
			
		/// <summary>
		/// Specifies the y-coordinate of the lower-right corner of the rectangle
		/// </summary>
		public int bottom;
	}
	
	
	/// <summary>
	/// Receives dynamic-link library (DLL)-specific version information. 
	/// It is used with the DllGetVersion function
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct DLLVERSIONINFO
	{
		/// <summary>
		/// Size of the structure, in bytes. This member must be filled 
		/// in before calling the function
		/// </summary>
		public int cbSize;

		/// <summary>
		/// Major version of the DLL. If the DLL's version is 4.0.950, 
		/// this value will be 4
		/// </summary>
		public int dwMajorVersion;

		/// <summary>
		/// Minor version of the DLL. If the DLL's version is 4.0.950, 
		/// this value will be 0
		/// </summary>
		public int dwMinorVersion;

		/// <summary>
		/// Build number of the DLL. If the DLL's version is 4.0.950, 
		/// this value will be 950
		/// </summary>
		public int dwBuildNumber;

		/// <summary>
		/// Identifies the platform for which the DLL was built
		/// </summary>
		public int dwPlatformID;
	}


	/// <summary>
	/// The NCCALCSIZE_PARAMS structure contains information that an application 
	/// can use while processing the WM_NCCALCSIZE message to calculate the size, 
	/// position, and valid contents of the client area of a window
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct NCCALCSIZE_PARAMS
	{
		/// <summary>
		/// Specifies an array of rectangles. The first contains the new 
		/// coordinates of a window that has been moved or resized, that 
		/// is, it is the proposed new window coordinates. The second 
		/// contains the coordinates of the window before it was moved or 
		/// resized. The third contains the coordinates of the window's 
		/// client area before the window was moved or resized. If the 
		/// window is a child window, the coordinates are relative to the 
		/// client area of the parent window. If the window is a top-level 
		/// window, the coordinates are relative to the screen origin
		/// </summary>
		public RECT rgrc0;
		public RECT rgrc1;
		public RECT rgrc2;

		/// <summary>
		/// Pointer to a WINDOWPOS structure that contains the size and 
		/// position values specified in the operation that moved or resized 
		/// the window
		/// </summary>
		public WINDOWPOS lppos;
	}


	/// <summary>
	/// The WINDOWPOS structure contains information about the size and position 
	/// of a window
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct WINDOWPOS
	{
		/// <summary>
		/// Handle to the window
		/// </summary>
		public IntPtr hwnd;
		
		/// <summary>
		/// Specifies the position of the window in Z order (front-to-back position). 
		/// This member can be a handle to the window behind which this window is placed, 
		/// or can be one of the SetWindowPosFlags values
		/// </summary>
		public IntPtr hwndInsertAfter;
		
		/// <summary>
		/// Specifies the position of the left edge of the window
		/// </summary>
		public int x;
		
		/// <summary>
		/// Specifies the position of the top edge of the window
		/// </summary>
		public int y;
		
		/// <summary>
		/// Specifies the window width, in pixels
		/// </summary>
		public int cx;
		
		/// <summary>
		/// Specifies the window height, in pixels
		/// </summary>
		public int cy;
		
		/// <summary>
		/// Specifies the window position. This member can be one or more of the 
		/// SetWindowPosFlags values
		/// </summary>
		public int flags;
	}


	/// <summary>
	/// The SCROLLINFO structure contains scroll bar parameters to be set by the 
	/// SetScrollInfo function, or retrieved by the GetScrollInfo function 
	/// </summary>
	[StructLayout(LayoutKind.Sequential)]
	public struct SCROLLINFO
	{
		/// <summary>
		/// Specifies the size, in bytes, of this structure. The caller must set 
		/// this to sizeof(SCROLLINFO)
		/// </summary>
		public int cbSize; 
		
		/// <summary>
		/// Specifies the scroll bar parameters to set or retrieve. This member 
		/// can be a combination of the ScrollInfoFlags values
		/// </summary>
		public int fMask; 
		
		/// <summary>
		/// Specifies the minimum scrolling position
		/// </summary>
		public int nMin; 
		
		/// <summary>
		/// Specifies the maximum scrolling position
		/// </summary>
		public int nMax; 
		
		/// <summary>
		/// Specifies the page size. A scroll bar uses this value to determine the 
		/// appropriate size of the proportional scroll box
		/// </summary>
		public int nPage; 
		
		/// <summary>
		/// Specifies the position of the scroll box
		/// </summary>
		public int nPos; 
		
		/// <summary>
		/// Specifies the immediate position of a scroll box that the user is dragging. 
		/// An application can retrieve this value while processing the SB_THUMBTRACK 
		/// request code. An application cannot set the immediate scroll position; the 
		/// SetScrollInfo function ignores this member
		/// </summary>
		public int nTrackPos; 
	}

	#endregion



	#region Flags

	#region Window Messages

	/// <summary>
	/// The WindowMessageFlags enemeration contains Windows messages that the 
	/// XPExplorerBar may be interested in listening for
	/// </summary>
	public enum WindowMessageFlags
	{
		/// <summary>
		/// The WM_NCCALCSIZE message is sent when the size and position of a 
		/// window's client area must be calculated. By processing this message, 
		/// an application can control the content of the window's client area 
		/// when the size or position of the window changes
		/// </summary>
		WM_NCCALCSIZE = 131,

		/// <summary>
		/// The WM_NCHITTEST message is sent to a window when the cursor moves, 
		/// or when a mouse button is pressed or released. If the mouse is not 
		/// captured, the message is sent to the window beneath the cursor. 
		/// Otherwise, the message is sent to the window that has captured the 
		/// mouse
		/// </summary>
		WM_NCHITTEST = 132,

		/// <summary>
		/// The WM_NCPAINT message is sent to a window when its frame must be 
		/// painted
		/// </summary>
		WM_NCPAINT = 133,

		/// <summary>
		/// The WM_HSCROLL message is sent to a window when a scroll event occurs 
		/// in the window's standard horizontal scroll bar. This message is also 
		/// sent to the owner of a horizontal scroll bar control when a scroll 
		/// event occurs in the control
		/// </summary>
		WM_HSCROLL = 276,

		/// <summary>
		/// The WM_VSCROLL message is sent to a window when a scroll event occurs 
		/// in the window's standard vertical scroll bar. This message is also sent 
		/// to the owner of a vertical scroll bar control when a scroll event occurs 
		/// in the control
		/// </summary>
		WM_VSCROLL = 277,
		
		/// <summary>
		/// The WM_PRINT message is sent to a window to request that it draw 
		/// itself in the specified device context, most commonly in a printer 
		/// device context
		/// </summary>
		WM_PRINT = 791,
			
		/// <summary>
		/// The WM_PRINTCLIENT message is sent to a window to request that it draw 
		/// its client area in the specified device context, most commonly in a 
		/// printer device context
		/// </summary>
		WM_PRINTCLIENT = 792
	}

	#endregion

	#region WmPrint

	/// <summary>
	/// The WmPrintFlags enemeration contains flags that may be sent 
	/// when a WM_PRINT or WM_PRINTCLIENT message is recieved
	/// </summary>
	public enum WmPrintFlags
	{
		/// <summary>
		/// Draws the window only if it is visible
		/// </summary>
		PRF_CHECKVISIBLE = 1,
		
		/// <summary>
		/// Draws the nonclient area of the window
		/// </summary>
		PRF_NONCLIENT = 2,
			
		/// <summary>
		/// Draws the client area of the window
		/// </summary>
		PRF_CLIENT = 4,
			
		/// <summary>
		/// Erases the background before drawing the window
		/// </summary>
		PRF_ERASEBKGND = 8,
			
		/// <summary>
		/// Draws all visible children windows
		/// </summary>
		PRF_CHILDREN = 16,
			
		/// <summary>
		/// Draws all owned windows
		/// </summary>
		PRF_OWNED = 32
	}

	#endregion

	#region LoadLibraryEx

	/// <summary>
	/// The LoadLibraryExFlags enemeration contains flags that control 
	/// how a .dll file is loaded with the NativeMethods.LoadLibraryEx 
	/// function
	/// </summary>
	public enum LoadLibraryExFlags
	{
		/// <summary>
		/// If this value is used, and the executable module is a DLL, 
		/// the system does not call DllMain for process and thread 
		/// initialization and termination. Also, the system does not 
		/// load additional executable modules that are referenced by 
		/// the specified module. If this value is not used, and the 
		/// executable module is a DLL, the system calls DllMain for 
		/// process and thread initialization and termination. The system 
		/// loads additional executable modules that are referenced by 
		/// the specified module
		/// </summary>
		DONT_RESOLVE_DLL_REFERENCES = 1,
		
		/// <summary>
		/// If this value is used, the system maps the file into the calling 
		/// process's virtual address space as if it were a data file. Nothing 
		/// is done to execute or prepare to execute the mapped file. Use 
		/// this flag when you want to load a DLL only to extract messages 
		/// or resources from it
		/// </summary>
		LOAD_LIBRARY_AS_DATAFILE = 2,
		
		/// <summary>
		/// If this value is used, and lpFileName specifies a path, the 
		/// system uses the alternate file search strategy to find associated 
		/// executable modules that the specified module causes to be loaded. 
		/// If this value is not used, or if lpFileName does not specify a 
		/// path, the system uses the standard search strategy to find 
		/// associated executable modules that the specified module causes 
		/// to be loaded
		/// </summary>
		LOAD_WITH_ALTERED_SEARCH_PATH = 8,
		
		/// <summary>
		/// If this value is used, the system does not perform automatic 
		/// trust comparisons on the DLL or its dependents when they are 
		/// loaded
		/// </summary>
		LOAD_IGNORE_CODE_AUTHZ_LEVEL = 16
	}

	#endregion

	#region SetErrorMode

	/// <summary>
	/// The SetErrorModeFlags enemeration contains flags that control 
	/// whether the system will handle the specified types of serious errors, 
	/// or whether the process will handle them
	/// </summary>
	public enum SetErrorModeFlags
	{
		/// <summary>
		/// Use the system default, which is to display all error dialog boxes
		/// </summary>
		SEM_DEFAULT = 0,
		
		/// <summary>
		/// The system does not display the critical-error-handler message box. 
		/// Instead, the system sends the error to the calling process
		/// </summary>
		SEM_FAILCRITICALERRORS = 1,
		
		/// <summary>
		/// The system does not display the general-protection-fault message box. 
		/// This flag should only be set by debugging applications that handle 
		/// general protection (GP) faults themselves with an exception handler
		/// </summary>
		SEM_NOGPFAULTERRORBOX = 2,
			
		/// <summary>
		/// After this value is set for a process, subsequent attempts to clear 
		/// the value are ignored. 64-bit Windows:  The system automatically fixes 
		/// memory alignment faults and makes them invisible to the application. 
		/// It does this for the calling process and any descendant processes
		/// </summary>
		SEM_NOALIGNMENTFAULTEXCEPT = 4,
			
		/// <summary>
		/// The system does not display a message box when it fails to find a 
		/// file. Instead, the error is returned to the calling process
		/// </summary>
		SEM_NOOPENFILEERRORBOX = 32768
	}

	#endregion

	#region SetWindowPosFlags

	/// <summary>
	/// The SetWindowPosFlags enemeration contains flags that control 
	/// how a window is positioned with the NativeMethods.SetWindowPos 
	/// function
	/// </summary>
	public enum SetWindowPosFlags
	{
		/// <summary>
		/// Retains the current size (ignores the cx and cy parameters)
		/// </summary>
		SWP_NOSIZE = 1,
		
		/// <summary>
		/// Retains the current position (ignores X and Y parameters)
		/// </summary>
		SWP_NOMOVE = 2,
		
		/// <summary>
		/// Retains the current Z order (ignores the hWndInsertAfter 
		/// parameter)
		/// </summary>
		SWP_NOZORDER = 4,
		
		/// <summary>
		/// Does not redraw changes. If this flag is set, no repainting 
		/// of any kind occurs. This applies to the client area, the nonclient 
		/// area (including the title bar and scroll bars), and any part 
		/// of the parent window uncovered as a result of the window being 
		/// moved. When this flag is set, the application must explicitly 
		/// invalidate or redraw any parts of the window and parent window 
		/// that need redrawing
		/// </summary>
		SWP_NOREDRAW = 8,
		
		/// <summary>
		/// Does not activate the window. If this flag is not set, the window 
		/// is activated and moved to the top of either the topmost or non-topmost 
		/// group (depending on the setting of the hWndInsertAfter parameter)
		/// </summary>
		SWP_NOACTIVATE = 16,
		
		/// <summary>
		/// Applies new frame styles set using the SetWindowLong function. 
		/// Sends a WM_NCCALCSIZE message to the window, even if the window's 
		/// size is not being changed. If this flag is not specified, WM_NCCALCSIZE 
		/// is sent only when the window's size is being changed
		/// </summary>
		SWP_FRAMECHANGED = 32,
		
		/// <summary>
		/// Displays the window
		/// </summary>
		SWP_SHOWWINDOW = 64,
		
		/// <summary>
		/// Hides the window
		/// </summary>
		SWP_HIDEWINDOW = 128,
		
		/// <summary>
		/// Discards the entire contents of the client area. If this flag is 
		/// not specified, the valid contents of the client area are saved and 
		/// copied back into the client area after the window is sized or repositioned
		/// </summary>
		SWP_NOCOPYBITS = 256,
		
		/// <summary>
		/// Does not change the owner window's position in the Z order
		/// </summary>
		SWP_NOOWNERZORDER = 512,
		
		/// <summary>
		/// Prevents the window from receiving the WM_WINDOWPOSCHANGING message
		/// </summary>
		SWP_NOSENDCHANGING = 1024,
		
		/// <summary>
		/// Draws a frame (defined in the window's class description) around 
		/// the window
		/// </summary>
		SWP_DRAWFRAME = SWP_FRAMECHANGED,
		
		/// <summary>
		/// Same as the SWP_NOOWNERZORDER flag
		/// </summary>
		SWP_NOREPOSITION = SWP_NOOWNERZORDER
	}

	#endregion

	#region RedrawWindowFlags

	/// <summary>
	/// The RedrawWindowFlags enemeration contains flags that control 
	/// how a window is drawn with the NativeMethods.RedrawWindow function
	/// </summary>
	public enum RedrawWindowFlags
	{
		/// <summary>
		/// Invalidates lprcUpdate or hrgnUpdate (only one may be non-NULL). 
		/// If both are NULL, the entire window is invalidated
		/// </summary>
		RDW_INVALIDATE = 1,
		
		/// <summary>
		/// Causes a WM_PAINT message to be posted to the window regardless of 
		/// whether any portion of the window is invalid
		/// </summary>
		RDW_INTERNALPAINT = 2,
		
		/// <summary>
		/// Causes the window to receive a WM_ERASEBKGND message when the window 
		/// is repainted. The RDW_INVALIDATE flag must also be specified; otherwise, 
		/// RDW_ERASE has no effect
		/// </summary>
		RDW_ERASE = 4,
		
		/// <summary>
		/// Validates lprcUpdate or hrgnUpdate (only one may be non-NULL). If 
		/// both are NULL, the entire window is validated. This flag does not 
		/// affect internal WM_PAINT messages
		/// </summary>
		RDW_VALIDATE = 8,
		
		/// <summary>
		/// Suppresses any pending internal WM_PAINT messages. This flag does 
		/// not affect WM_PAINT messages resulting from a non-NULL update area
		/// </summary>
		RDW_NOINTERNALPAINT = 16,
		
		/// <summary>
		/// Suppresses any pending WM_ERASEBKGND messages
		/// </summary>
		RDW_NOERASE = 32,
		
		/// <summary>
		/// Excludes child windows, if any, from the repainting operation
		/// </summary>
		RDW_NOCHILDREN = 64,
		
		/// <summary>
		/// Includes child windows, if any, in the repainting operation
		/// </summary>
		RDW_ALLCHILDREN = 128,
		
		/// <summary>
		/// Causes the affected windows (as specified by the RDW_ALLCHILDREN and 
		/// RDW_NOCHILDREN flags) to receive WM_NCPAINT, WM_ERASEBKGND, and 
		/// WM_PAINT messages, if necessary, before the function returns
		/// </summary>
		RDW_UPDATENOW = 256,
		
		/// <summary>
		/// Causes the affected windows (as specified by the RDW_ALLCHILDREN and 
		/// RDW_NOCHILDREN flags) to receive WM_NCPAINT and WM_ERASEBKGND messages, 
		/// if necessary, before the function returns. WM_PAINT messages are received 
		/// at the ordinary time
		/// </summary>
		RDW_ERASENOW = 512,
		
		/// <summary>
		/// Causes any part of the nonclient area of the window that intersects the 
		/// update region to receive a WM_NCPAINT message. The RDW_INVALIDATE flag 
		/// must also be specified; otherwise, RDW_FRAME has no effect. The WM_NCPAINT 
		/// message is typically not sent during the execution of RedrawWindow unless 
		/// either RDW_UPDATENOW or RDW_ERASENOW is specified
		/// </summary>
		RDW_FRAME = 1024,
		
		/// <summary>
		/// Suppresses any pending WM_NCPAINT messages. This flag must be used with 
		/// RDW_VALIDATE and is typically used with RDW_NOCHILDREN. RDW_NOFRAME 
		/// should be used with care, as it could cause parts of a window to be 
		/// painted improperly
		/// </summary>
		RDW_NOFRAME = 2048
	}

	#endregion

	#region ScrollBarConstants

	/// <summary>
	/// The ScrollBarConstants enemeration contains flags that are used with 
	/// the NativeMethods.ShowScrollBar, NativeMethods.EnableScrollBar, 
	/// NativeMethods.GetScrollInfo and NativeMethods.SetScrollInfo functions
	/// </summary>
	public enum ScrollBarConstants
	{
		/// <summary>
		/// Horizontal scroll bar
		/// </summary>
		SB_HORZ = 0,
		
		/// <summary>
		/// Vertical scroll bar
		/// </summary>
		SB_VERT = 1,
		
		/// <summary>
		/// Horizontal and Vertical scroll bars
		/// </summary>
		SB_BOTH = 3
	}

	#endregion

	#region EnableScrollBarFlags

	/// <summary>
	/// The EnableScrollBarFlags enemeration contains flags that control 
	/// which scrollbars are enabled/disabled with the NativeMethods.EnableScrollBar 
	/// function
	/// </summary>
	public enum EnableScrollBarFlags
	{
		/// <summary>
		/// Enables both arrows on a scroll bar
		/// </summary>
		ESB_ENABLE_BOTH = 0,
		
		/// <summary>
		/// Disables both arrows on a scroll bar
		/// </summary>
		ESB_DISABLE_BOTH = 3,
		
		/// <summary>
		/// Disables the left arrow on a horizontal scroll bar
		/// </summary>
		ESB_DISABLE_LEFT = 1,
		
		/// <summary>
		/// Disables the right arrow on a horizontal scroll bar
		/// </summary>
		ESB_DISABLE_RIGHT = 2,
		
		/// <summary>
		/// Disables the up arrow on a vertical scroll bar
		/// </summary>
		ESB_DISABLE_UP = 1,
		
		/// <summary>
		/// Disables the down arrow on a vertical scroll bar
		/// </summary>
		ESB_DISABLE_DOWN = 2,
		
		/// <summary>
		/// Disables the left arrow on a horizontal scroll bar or 
		/// the up arrow of a vertical scroll bar
		/// </summary>
		ESB_DISABLE_LTUP = ESB_DISABLE_LEFT,
		
		/// <summary>
		/// Disables the right arrow on a horizontal scroll bar or 
		/// the down arrow of a vertical scroll bar
		/// </summary>
		ESB_DISABLE_RTDN = ESB_DISABLE_RIGHT
	}

	#endregion

	#region ScrollInfoFlags

	/// <summary>
	/// The EnableScrollBarFlags enemeration contains flags that control 
	/// scrollbar information with the NativeMethods.SetScrollInfo and 
	/// NativeMethods.GetScrollInfo functions
	/// </summary>
	public enum ScrollInfoFlags
	{
		/// <summary>
		/// The nMin and nMax members contain the minimum and maximum values for 
		/// the scrolling range
		/// </summary>
		SIF_RANGE = 1,
		
		/// <summary>
		/// The nPage member contains the page size for a proportional scroll bar
		/// </summary>
		SIF_PAGE = 2,
		
		/// <summary>
		/// The nPos member contains the scroll box position, which is not updated 
		/// while the user drags the scroll box
		/// </summary>
		SIF_POS = 4,
		
		/// <summary>
		/// This value is used only when setting a scroll bar's parameters. If the 
		/// scroll bar's new parameters make the scroll bar unnecessary, disable the 
		/// scroll bar instead of removing it
		/// </summary>
		SIF_DISABLENOSCROLL = 8,
		
		/// <summary>
		/// The nTrackPos member contains the current position of the scroll box while 
		/// the user is dragging it
		/// </summary>
		SIF_TRACKPOS = 16,
		
		/// <summary>
		/// Combination of SIF_PAGE, SIF_POS, SIF_RANGE, and SIF_TRACKPOS
		/// </summary>
		SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
	}

	#endregion

	#endregion
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


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

Comments and Discussions