|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Windows.Forms.VisualStyles;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;
namespace Guide.Controls
{
/// <summary>
/// An enhanced ListBox which correctly handles and provides better control over horizontal scrolling.
/// </summary>
public class ProperListBox : ListBox
{
private int horzScrollBarValue = 0;
public ProperListBox()
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
// this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true);
}
protected override void OnPaint(PaintEventArgs e)
{
Region iRegion = new Region(e.ClipRectangle);
e.Graphics.FillRegion(new SolidBrush(this.BackColor), iRegion);
for (int i = 0; i < this.Items.Count; ++i)
{
System.Drawing.Rectangle irect = this.GetItemRectangle(i);
if (e.ClipRectangle.IntersectsWith(irect))
{
if ((this.SelectionMode == SelectionMode.One && this.SelectedIndex == i)
|| (this.SelectionMode == SelectionMode.MultiSimple && this.SelectedIndices.Contains(i))
|| (this.SelectionMode == SelectionMode.MultiExtended && this.SelectedIndices.Contains(i)))
{
OnDrawItem(new DrawItemEventArgs(e.Graphics, this.Font,
irect, i,
DrawItemState.Selected, this.ForeColor,
this.BackColor));
}
else
{
OnDrawItem(new DrawItemEventArgs(e.Graphics, this.Font,
irect, i,
DrawItemState.Default, this.ForeColor,
this.BackColor));
}
iRegion.Complement(irect);
}
}
base.OnPaint(e);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (this.HorizontalScrollbar && m.Msg == PInvokeHelp.WM_HSCROLL || m.Msg == PInvokeHelp.WM_MOUSEWHEEL)
{
// Debug.WriteLine("WParam = " + m.WParam.ToInt32().ToString() + " LParam = " + m.LParam.ToInt32().ToString());
// Update Scroll position
PInvokeHelp.SCROLLINFO si = new PInvokeHelp.SCROLLINFO();
si.cbSize = Marshal.SizeOf(si);
si.fMask = PInvokeHelp.SIF_ALL;
if (PInvokeHelp.GetScrollInfo(m.HWnd, PInvokeHelp.SB_HORZ, ref si))
horzScrollBarValue = si.nPos;
// Debug.WriteLine("Position = " + si.nPos.ToString() + "; " + si.nTrackPos.ToString());
// Callback
if (this.HorizontalScrolled != null)
this.HorizontalScrolled(this, EventArgs.Empty);
}
}
public new bool HorizontalScrollbar
{
get
{
return base.HorizontalScrollbar;
}
set
{
base.HorizontalScrollbar = value;
if (!base.HorizontalScrollbar)
{
base.HorizontalExtent = 0;
this.HScrollPosition = 0;
}
ForceUpdateHScroll();
}
}
/// <summary>
/// Gets or sets the width by which the horizontal scroll bar of a ListBox
/// </summary>
/// <returns>
/// The width, in pixels, that the horizontal scroll bar can scroll the control. The default is zero.
/// </returns>
[DefaultValue(0)]
[Localizable(true)]
public new int HorizontalExtent
{
get
{
return base.HorizontalExtent;
}
set
{
base.HorizontalExtent = value;
ForceUpdateHScroll();
}
}
/// <summary>
/// Gets or sets the width by which the horizontal scroll bar of a ListBox can scroll.
/// </summary>
/// <returns>
/// The width, in pixels, that the horizontal scroll bar can scroll the control. The default is zero.
/// </returns>
[DefaultValue(0)]
[Localizable(true)]
public int HScrollPosition
{
get
{
return horzScrollBarValue;
}
set
{
PInvokeHelp.SCROLLINFO si = new PInvokeHelp.SCROLLINFO();
si.cbSize = Marshal.SizeOf(si);
si.fMask = PInvokeHelp.SIF_POS;
si.nPos = value;
horzScrollBarValue = PInvokeHelp.SetScrollInfo(this.Handle, PInvokeHelp.SB_HORZ, ref si, true);
ForceUpdateHScroll();
}
}
protected void ForceUpdateHScroll()
{
PInvokeHelp.SendMessage(this.Handle, PInvokeHelp.WM_HSCROLL, PInvokeHelp.MakeDWord(PInvokeHelp.SB_THUMBPOSITION, this.HScrollPosition), 0);
}
/// <summary>
/// Occurs when the horizontal scroll bar scrolls.
/// </summary>
public event EventHandler HorizontalScrolled;
class PInvokeHelp
{
public const int WM_HSCROLL = 0x0114;
public const int WM_MOUSEWHEEL = 0x20A;
public static int HiWord(int value)
{
return (int)(value & 0xFFFF0000) >> 16;
}
public static int LoWord(int value)
{
return (int)(value & 0x0000FFFF);
}
public static long MakeDWord(int lo, int hi)
{
return (lo | (hi << 16));
}
[StructLayout(LayoutKind.Sequential)]
public struct SCROLLINFO
{
public int cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
// ScrollBarDirection
public const int SB_HORZ = 0;
public const int SB_VERT = 1;
public const int SB_CTL = 2;
public const int SB_BOTH = 3;
// ScrollInfoMask
public const int SIF_RANGE = 0x1;
public const int SIF_PAGE = 0x2;
public const int SIF_POS = 0x4;
public const int SIF_DISABLENOSCROLL = 0x8;
public const int SIF_TRACKPOS = 0x10;
public const int SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS;
// ScrollBarCommands
public const int SB_LINEUP = 0;
public const int SB_LINELEFT = 0;
public const int SB_LINEDOWN = 1;
public const int SB_LINERIGHT = 1;
public const int SB_PAGEUP = 2;
public const int SB_PAGELEFT = 2;
public const int SB_PAGEDOWN = 3;
public const int SB_PAGERIGHT = 3;
public const int SB_THUMBPOSITION = 4;
public const int SB_THUMBTRACK = 5;
public const int SB_TOP = 6;
public const int SB_LEFT = 6;
public const int SB_BOTTOM = 7;
public const int SB_RIGHT = 7;
public const int SB_ENDSCROLL = 8;
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, uint Msg, long wParam, long lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);
[DllImport("user32.dll")]
public static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi, bool fRedraw);
}
}
}
|
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.