using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace MyProject
{
/// <summary>
/// Extends the ColorDialog class and allows the initial location of the window to be specified.
/// </summary>
public class ColorDialogEx : ColorDialog
{
#region Types
/// <summary>
/// Defines values that can be assigned to the Flags field of a WindowPos object.
/// </summary>
[Flags()]
private enum WindowPosFlags : uint
{
NoResize = 0x1,
NoMove = 0x2,
NoZOrder = 0x4,
NoRedraw = 0x8,
NoActivate = 0x10,
FrameChanged = 0x20,
ShowWindow = 0x40,
HideWindow = 0x80,
NoCopyBits = 0x100,
NoOwnerZOrder = 0x200,
NoSendChanging = 0x400,
DeferErase = 0x2000,
AsyncWindowPos = 0x4000
}
/// <summary>
/// Received as the lParam value when a WM_WINDOWPOSCHANGING message is received.
/// </summary>
private struct WindowPos
{
public IntPtr HWnd;
public IntPtr HWndInsertAfter;
public int X;
public int Y;
public int Cx;
public int Cy;
public WindowPosFlags Flags;
}
#endregion // Types
#region Constants
/// <summary>
/// The message received when the window position is changing.
/// </summary>
private const int WM_WINDOWPOSCHANGING = 0x46;
#endregion // Constants
#region Variables
/// <summary>
/// The location at which the window will be initially displayed.
/// </summary>
/// <remarks>
/// If no value is assigned the window is displayed at the default location.
/// </remarks>
private Point? initialLocation = null;
#endregion // Variables
#region Constructors
/// <summary>
/// Creates a new instance of the ColorDialogEx class.
/// </summary>
public ColorDialogEx()
: base()
{
}
/// <summary>
/// Creates a new instance of the ColorDialogEx class.
/// </summary>
/// <param name="initialLocation">
/// The location at which the window will be initially dispalyed.
/// </param>
public ColorDialogEx(Point initialLocation)
: this()
{
this.initialLocation = initialLocation;
}
#endregion // Constructors
#region Methods
/// <summary>
/// Hooks into the common dialog's message queue.
/// </summary>
/// <param name="hWnd">
/// The handle to the native window.
/// </param>
/// <param name="msg">
/// The message received from the operating system.
/// </param>
/// <param name="wparam">
/// Message-specific data.
/// </param>
/// <param name="lparam">
/// Message-specific data.
/// </param>
/// <returns>
/// A zero value if the default dialog box procedure processes the message; a nonzero value if the default dialog box procedure ignores the message.
/// </returns>
protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
{
// Trap the WM_WINDOWPOSCHANGING message if an initial location has been specified.
if (msg == WM_WINDOWPOSCHANGING && this.initialLocation.HasValue)
{
// Get the data provided by the OS.
WindowPos pos = (WindowPos)Marshal.PtrToStructure(lparam, typeof(WindowPos));
// Look for the specific combination of flags that indicates that
// this is the appropriate message on which to set the location.
if (pos.Flags == (WindowPosFlags.NoResize | WindowPosFlags.NoZOrder | WindowPosFlags.NoActivate))
{
pos.X = this.initialLocation.Value.X;
pos.Y = this.initialLocation.Value.Y;
// Make the new data available to unmanaged code.
Marshal.StructureToPtr(pos, lparam, true);
}
}
// Pass on the message.
return base.HookProc(hWnd, msg, wparam, lparam);
}
#endregion // Methods
}
}