vbAccelerator - Contents of code file: RichEditAutoComplete_DropDownPosition.cs
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace vbAccelerator.Components.Controls
{
/// <summary>
/// A class for extending a combo box to allow the drop down
/// to be independently positioned.
/// </summary>
/// <remarks>
/// <para>Use the <see cref="System.Windows.Forms.AssignHandle"/>
/// method to connect this instance to a combo box. If you change a combo
/// box property which causes its window handle to be recreated (such
/// as setting the <see cref="System.Windows.Forms.ComboBoxStyle"/>) then
this class
/// will need to be reassigned. You can override the ComboBox's
/// <see cref="System.Windows.Forms.ComboBox.OnHandleCreated"/>
/// to do this assignment automatically.</para>
/// <para>To show the drop down at a position, use the ComboBox's
/// <see cref="System.Windows.Forms.ComboBox.DroppedDown"/> property to set
<c>true</c>
/// to drop-down the box, then call the <see
cref="System.Windows.Forms.ComboBox.Focus"/>
/// method to ensure keyboard events are passed to the combo box.
/// </para>
/// </remarks>
public class DropDownPosition : NativeWindow
{
#region Unmanaged Code
/// <summary>
/// The message which provides the handle of the ListBox
/// portion of the combo box control. Can also be used to
/// set the background colour of the ListBox.
/// </summary>
private const int WM_CTLCOLORLISTBOX = 0x134;
/// <summary>
/// Gets the parent the window with the specified handle.
/// </summary>
[DllImport("user32")]
private static extern IntPtr GetParent (IntPtr hWnd);
/// <summary>
/// Move a Window with the specified handle to a location.
/// </summary>
[DllImport("user32")]
private static extern int MoveWindow (IntPtr hwnd, int x, int y, int
nWidth, int nHeight , bool bRepaint );
/// <summary>
/// Returns 1 (<c>true</c>) if the specified <c>hwnd</c> (handle) is a
Window or not.
/// </summary>
[DllImport("user32")]
private static extern bool IsWindow (IntPtr hwnd );
/// <summary>
/// A Win32 API rectangle
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
/// <summary>
/// Gets the rectangle of a window givent it's handle.
/// </summary>
[DllImport("user32")]
private static extern bool GetWindowRect(IntPtr hwnd, ref RECT lpRect);
#endregion
#region Member Variables
/// <summary>
/// Where to show the drop-down at
/// </summary>
private Point dropDownPosition;
/// <summary>
/// Whether to move the drop-down or not.
/// </summary>
private bool positionDropDown = false;
/// <summary>
/// The window handle of the drop-down list box portion of
/// the combo box.
/// </summary>
private IntPtr m_hWndDropDown = IntPtr.Zero;
/// <summary>
/// Class to detect Combo Close Up events.
/// </summary>
private ComboCloseUpDetector closeUpDetector;
#endregion
#region Events
/// <summary>
/// Raised when the combo box is closed up.
/// </summary>
public event System.EventHandler CloseUp;
#endregion
/// <summary>
/// Gets the handle of the drop-down portion of the
/// assigned combo box if any. The handle is only
/// correct once the combo box has been dropped down
/// at least once.
/// </summary>
public IntPtr DropDownHandle
{
get
{
return this.m_hWndDropDown;
}
}
/// <summary>
/// Gets/sets whether this class wil position the
/// drop-down or not.
/// </summary>
public bool PositionDropDown
{
get
{
return positionDropDown;
}
set
{
positionDropDown = value;
}
}
/// <summary>
/// Gets/sets the position to show the drop-down at.
/// </summary>
public Point DropDownLocation
{
get
{
return dropDownPosition;
}
set
{
dropDownPosition = value;
}
}
/// <summary>
/// Performs default Window Procedure processing and
/// allows the drop-down portion of the combo box to
/// be moved.
/// </summary>
/// <param name="m">Window Procedure Message</param>
protected override void WndProc(ref System.Windows.Forms.Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case (WM_CTLCOLORLISTBOX):
m_hWndDropDown = m.LParam;
if (positionDropDown)
{
if (IsWindow(m_hWndDropDown))
{
RECT dropDownRect = new RECT();
GetWindowRect(m_hWndDropDown, ref dropDownRect);
MoveWindow(m_hWndDropDown,
dropDownPosition.X, dropDownPosition.Y,
dropDownRect.right - dropDownRect.left,
dropDownRect.bottom - dropDownRect.top,
true);
}
}
break;
}
}
private void closeUpDetector_CloseUp(object sender, EventArgs e)
{
if (this.CloseUp != null)
{
this.CloseUp(this, e);
}
}
/// <summary>
/// Assigns this class to the specified ComboBox window handle
/// and enables tracking for drop-downs and
/// </summary>
/// <param name="handle"></param>
public new void AssignHandle(IntPtr handle)
{
base.AssignHandle(handle);
closeUpDetector = new ComboCloseUpDetector(handle);
closeUpDetector.AssignHandle(GetParent(handle));
closeUpDetector.CloseUp += new EventHandler(closeUpDetector_CloseUp);
}
/// <summary>
/// Default constructor for class
/// </summary>
public DropDownPosition()
{
// intentionally blank
}
}
}
|
|