📄 commandbar.cs
字号:
// ---------------------------------------------------------
// Windows Forms CommandBar Control
// Copyright (C) 2001-2003 Lutz Roeder. All rights reserved.
// http://www.aisto.com/roeder
// roeder@aisto.com
// ---------------------------------------------------------
namespace Reflector.UserInterface
{
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;
public class CommandBar : Control, IDisposable
{
private CommandBarItemCollection items = new CommandBarItemCollection();
private CommandBarStyle style = CommandBarStyle.ToolBar;
private CommandBarContextMenu contextMenu = new CommandBarContextMenu();
private IntPtr hookHandle = IntPtr.Zero;
private Point lastMousePosition = new Point(0, 0);
private int trackHotItem = -1;
private int trackNextItem = -1;
private bool trackEscapePressed = false;
private State state = State.None;
private State lastState = State.None;
private ImageList imageList;
private bool useChevron = true;
private bool newLine = false;
private enum State
{
None,
Hot,
HotTracking
}
public CommandBar()
{
this.items = new CommandBarItemCollection(this);
this.SetStyle(ControlStyles.UserPaint, false);
this.TabStop = false;
this.Font = SystemInformation.MenuFont;
this.Dock = DockStyle.Top;
}
public CommandBar(CommandBarStyle style) : this()
{
this.style = style;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.items.Clear();
this.items = null;
this.contextMenu = null;
}
base.Dispose(disposing);
}
public CommandBarStyle Style
{
set
{
this.style = value;
this.UpdateItems();
}
get
{
return this.style;
}
}
public CommandBarItemCollection Items
{
get
{
return this.items;
}
}
public bool NewLine
{
get
{
return newLine;
}
set
{
newLine = value;
}
}
public bool UseChevron
{
get
{
return useChevron;
}
set
{
useChevron = value;
}
}
protected override Size DefaultSize
{
get
{
return new Size(100, 22);
}
}
protected override void CreateHandle()
{
if (!this.RecreatingHandle)
{
NativeMethods.INITCOMMONCONTROLSEX icex = new NativeMethods.INITCOMMONCONTROLSEX();
icex.Size = Marshal.SizeOf(typeof(NativeMethods.INITCOMMONCONTROLSEX));
icex.Flags = NativeMethods.ICC_BAR_CLASSES | NativeMethods.ICC_COOL_CLASSES;
NativeMethods.InitCommonControlsEx(icex);
}
base.CreateHandle();
}
protected override CreateParams CreateParams
{
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
get
{
CreateParams createParams = base.CreateParams;
createParams.ClassName = NativeMethods.TOOLBARCLASSNAME;
createParams.ExStyle = 0;
createParams.Style = NativeMethods.WS_CHILD | NativeMethods.WS_VISIBLE | NativeMethods.WS_CLIPCHILDREN | NativeMethods.WS_CLIPSIBLINGS;
createParams.Style |= NativeMethods.CCS_NODIVIDER | NativeMethods.CCS_NORESIZE | NativeMethods.CCS_NOPARENTALIGN;
createParams.Style |= NativeMethods.TBSTYLE_TOOLTIPS | NativeMethods.TBSTYLE_FLAT | NativeMethods.TBSTYLE_TRANSPARENT;
if (Style == CommandBarStyle.Menu)
{
createParams.Style |= NativeMethods.TBSTYLE_LIST;
}
return createParams;
}
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
this.AddItems();
}
public bool IsAltGRPressed {
get {
return NativeMethods.GetAsyncKeyState(NativeMethods.VK_RMENU) < 0 && (Control.ModifierKeys & Keys.Control) == Keys.Control;
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
public override bool PreProcessMessage(ref Message message)
{
if (message.Msg == NativeMethods.WM_KEYDOWN || message.Msg == NativeMethods.WM_SYSKEYDOWN)
{
// Process shortcuts.
Keys keyData = (Keys) (int) message.WParam | ModifierKeys;
if (state == State.None && !IsAltGRPressed)
{
CommandBarItem[] shortcutHits = this.items[keyData];
if (shortcutHits.Length > 0)
{
if (this.PerformClick(shortcutHits[0]))
{
Console.WriteLine("SHORTCUTS PROCESSED");
return true;
}
}
}
}
// All the following code is for MenuBar only.
if (this.Style != CommandBarStyle.Menu)
{
return false;
}
if ((message.Msg >= NativeMethods.WM_LBUTTONDOWN) && (message.Msg <= NativeMethods.WM_MOUSELAST))
{
// Check if user clicked outside the MenuBar and end tracking.
if ((message.HWnd != Handle) && (this.state != State.None))
{
this.SetState(State.None, -1);
}
}
else if ((message.Msg == NativeMethods.WM_SYSKEYUP) || (message.Msg == NativeMethods.WM_KEYDOWN) || (message.Msg == NativeMethods.WM_SYSKEYDOWN))
{
Keys keyData = ((Keys) (int) message.WParam) | ModifierKeys;
Keys keyCode = ((Keys) (int) message.WParam);
if ((keyData == Keys.F10) || (keyCode == Keys.Menu))
{
if (message.Msg == NativeMethods.WM_SYSKEYUP)
{
if ((this.state == State.Hot) || (this.lastState == State.HotTracking))
{
this.SetState(State.None, 0);
}
else if (state == State.None)
{
this.SetState(State.Hot, 0);
}
return true;
}
}
else if (message.Msg == NativeMethods.WM_KEYDOWN || message.Msg == NativeMethods.WM_SYSKEYDOWN)
{
if (PreProcessKeyDown(ref message))
return true;
}
}
return base.PreProcessMessage(ref message);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (this.Style == CommandBarStyle.Menu)
{
if ((e.Button == MouseButtons.Left) && (e.Clicks == 1))
{
Point point = new Point(e.X, e.Y);
int index = this.HitTest(point);
if (this.IsValid(index))
{
this.TrackDropDown(index);
return;
}
}
}
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (this.Style == CommandBarStyle.Menu)
{
Point point = new Point(e.X, e.Y);
if (this.state == State.Hot)
{
int index = this.HitTest(point);
if ((this.IsValid(index)) && (point != lastMousePosition))
this.SetHotItem(index);
return;
}
lastMousePosition = point;
}
base.OnMouseMove(e);
}
private bool PreProcessKeyDown(ref Message message)
{
Keys keyData = (Keys)(int) message.WParam | ModifierKeys;
if (state == State.Hot)
{
int hotItem = this.GetHotItem();
if (hotItem != -1)
{
if (keyData == Keys.Left)
{
this.SetHotItem(this.GetPreviousItem(hotItem));
return true;
}
if (keyData == Keys.Right)
{
this.SetHotItem(this.GetNextItem(hotItem));
return true;
}
if ((keyData == Keys.Up) || (keyData == Keys.Down) || (keyData == Keys.Enter))
{
this.TrackDropDown(hotItem);
return true;
}
}
if (keyData == Keys.Escape)
{
this.SetState(State.None, -1);
return true;
}
}
bool alt = ((keyData & Keys.Alt) != 0) && !IsAltGRPressed;
if ((state == State.Hot) || (alt))
{
Keys keyCode = keyData & Keys.KeyCode;
char key = (char) (int) keyCode;
if ((Char.IsDigit(key) || (Char.IsLetter(key))))
{
// Process mnemonics.
if (this.PreProcessMnemonic(keyCode))
return true;
if ((state == State.Hot) && (!alt))
{
NativeMethods.MessageBeep(0);
return true;
}
}
}
// return to default state if not handled
if (state != State.None)
{
this.SetState(State.None, -1);
}
return false;
}
private bool PreProcessMnemonic(Keys keyCode)
{
char mnemonic = (char) (int) keyCode;
CommandBarItem[] mnemonicHits = this.items[mnemonic];
if (mnemonicHits.Length > 0 && mnemonicHits[0].IsVisible)
{
int index = items.IndexOf(mnemonicHits[0]);
this.TrackDropDown(index);
return true;
}
return false;
}
private bool IsValid(int index)
{
int count = NativeMethods.SendMessage(Handle, NativeMethods.TB_BUTTONCOUNT, 0, 0);
return ((index >= 0) && (index < count));
}
private int HitTest(Point point)
{
NativeMethods.POINT pt = new NativeMethods.POINT();
pt.x = point.X;
pt.y = point.Y;
int hit = NativeMethods.SendMessage(Handle, NativeMethods.TB_HITTEST, 0, ref pt);
if (hit > 0)
{
point = this.PointToScreen(point);
Rectangle bounds = this.RectangleToScreen(new Rectangle(0, 0, Width, Height));
if (!bounds.Contains(point))
{
return -1;
}
}
return hit;
}
private int GetNextItem(int index)
{
if (index < 0)
{
throw new ArgumentException("index");
}
int count = NativeMethods.SendMessage(this.Handle, NativeMethods.TB_BUTTONCOUNT, 0, 0);
int nextIndex = index;
do
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -