Click here to Skip to main content
15,886,724 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>
	/// A class that provides access to the Win32 API
	/// </summary>
	public sealed 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">Pointer to a null-terminated 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 a handle to the mapped 
		/// executable module. If the function fails, the return value is NULL.</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">Handle to the loaded DLL module. The LoadLibrary 
		/// function returns this handle</param>
		/// <returns>If the function succeeds, the return value is nonzero. If the 
		/// function fails, the return value is zero</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">Handle to the module whose executable file contains 
		/// the resource. A value of NULL specifies the module handle associated with 
		/// the image file that the operating system used to create the current process</param>
		/// <param name="lpName">Specifies the name of the resource</param>
		/// <param name="lpType">Specifies the resource type</param>
		/// <returns>If the function succeeds, the return value is a handle to the 
		/// specified resource's information block. To obtain a handle to the resource, 
		/// pass this handle to the LoadResource function. If the function fails, the 
		/// return value is NULL</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">Handle to the module whose executable file contains 
		/// the resource. A value of NULL specifies the module handle associated with 
		/// the image file that the operating system used to create the current process</param>
		/// <param name="lpName">Specifies the name of the resource</param>
		/// <param name="lpType">Specifies the resource type</param>
		/// <returns>If the function succeeds, the return value is a handle to the 
		/// specified resource's information block. To obtain a handle to the resource, 
		/// pass this handle to the LoadResource function. If the function fails, the 
		/// return value is NULL</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">Handle to the module whose executable file contains 
		/// the resource</param>
		/// <param name="hResInfo">Handle to the resource. This handle must be created 
		/// by using the FindResource or FindResourceEx 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">Handle to the module whose executable file contains 
		/// the resource. If hModule is NULL, the system loads the resource from the 
		/// module that was used to create the current process</param>
		/// <param name="hResInfo">Handle to the resource to be loaded. This handle is 
		/// returned by the FindResource or FindResourceEx function</param>
		/// <returns>If the function succeeds, the return value is a handle to the data 
		/// associated with the resource. If the function fails, the return value is NULL</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">Handle of 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">Pointer to the starting address of the copied 
		/// block's destination</param>
		/// <param name="Source">Pointer 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">Handle to the instance of the module whose executable 
		/// file contains the bitmap to be loaded</param>
		/// <param name="lpBitmapName">Pointer 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 the handle to the specified 
		/// bitmap. If the function fails, the return value is NULL</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">Handle 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">Pointer 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">Handle to the window whose window procedure will 
		/// receive the message</param>
		/// <param name="msg">Specifies the message to be sent</param>
		/// <param name="wParam">Specifies additional message-specific information</param>
		/// <param name="lParam">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">Handle to the DLL module that contains the function 
		/// or variable. The LoadLibrary or GetModuleHandle function returns this handle</param>
		/// <param name="procName">Pointer to a null-terminated 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 the address of the 
		/// exported function or variable. If the function fails, the return value is NULL</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);
	}

	#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;
	}

	#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_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

	#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