#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

195 lines
7.4 KiB

// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Reflection;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.FormsDesigner
{
public sealed class FormKeyHandler : IMessageFilter
{
const int keyPressedMessage = 0x100;
const int leftMouseButtonDownMessage = 0x0202;
readonly Dictionary<Keys, CommandWrapper> keyTable = new Dictionary<Keys, CommandWrapper>();
public static bool inserted = false;
public static void Insert()
{
inserted = true;
Application.AddMessageFilter(new FormKeyHandler());
}
public FormKeyHandler()
{
// normal keys
keyTable[Keys.Left] = new CommandWrapper(MenuCommands.KeyMoveLeft);
keyTable[Keys.Right] = new CommandWrapper(MenuCommands.KeyMoveRight);
keyTable[Keys.Up] = new CommandWrapper(MenuCommands.KeyMoveUp);
keyTable[Keys.Down] = new CommandWrapper(MenuCommands.KeyMoveDown);
keyTable[Keys.Tab] = new CommandWrapper(MenuCommands.KeySelectNext);
keyTable[Keys.Delete] = new CommandWrapper(MenuCommands.Delete);
keyTable[Keys.Back] = new CommandWrapper(MenuCommands.Delete);
// shift modified keys
keyTable[Keys.Left | Keys.Shift] = new CommandWrapper(MenuCommands.KeySizeWidthDecrease);
keyTable[Keys.Right | Keys.Shift] = new CommandWrapper(MenuCommands.KeySizeWidthIncrease);
keyTable[Keys.Up | Keys.Shift] = new CommandWrapper(MenuCommands.KeySizeHeightDecrease);
keyTable[Keys.Down | Keys.Shift] = new CommandWrapper(MenuCommands.KeySizeHeightIncrease);
keyTable[Keys.Tab | Keys.Shift] = new CommandWrapper(MenuCommands.KeySelectPrevious);
keyTable[Keys.Delete| Keys.Shift] = new CommandWrapper(MenuCommands.Delete);
keyTable[Keys.Back| Keys.Shift] = new CommandWrapper(MenuCommands.Delete);
// ctrl modified keys
keyTable[Keys.Left | Keys.Control] = new CommandWrapper(MenuCommands.KeyNudgeLeft);
keyTable[Keys.Right | Keys.Control] = new CommandWrapper(MenuCommands.KeyNudgeRight);
keyTable[Keys.Up | Keys.Control] = new CommandWrapper(MenuCommands.KeyNudgeUp);
keyTable[Keys.Down | Keys.Control] = new CommandWrapper(MenuCommands.KeyNudgeDown);
// ctrl + shift modified keys
keyTable[Keys.Left | Keys.Control | Keys.Shift] = new CommandWrapper(MenuCommands.KeyNudgeWidthDecrease);
keyTable[Keys.Right | Keys.Control | Keys.Shift] = new CommandWrapper(MenuCommands.KeyNudgeWidthIncrease);
keyTable[Keys.Up | Keys.Control | Keys.Shift] = new CommandWrapper(MenuCommands.KeyNudgeHeightDecrease);
keyTable[Keys.Down | Keys.Control | Keys.Shift] = new CommandWrapper(MenuCommands.KeyNudgeHeightIncrease);
}
public bool PreFilterMessage(ref Message m)
{
if (m.Msg != keyPressedMessage /*&& m.Msg != leftMouseButtonDownMessage*/) {
return false;
}
FormsDesignerViewContent formDesigner = WorkbenchSingleton.Workbench.ActiveContent as FormsDesignerViewContent;
if (formDesigner == null || formDesigner.Host == null) {
return false;
}
if (formDesigner.UserContent != null && !((Control)formDesigner.UserContent).ContainsFocus) {
return false;
}
Control originControl = Control.FromChildHandle(m.HWnd);
if (originControl != null && formDesigner.UserContent != null && !(formDesigner.UserContent == originControl || formDesigner.UserContent.Contains(originControl))) {
// Ignore if message origin not in forms designer
// (e.g. navigating the main menu)
return false;
}
Keys keyPressed = (Keys)m.WParam.ToInt32() | Control.ModifierKeys;
if (keyPressed == Keys.Escape) {
if (formDesigner.IsTabOrderMode) {
formDesigner.HideTabOrder();
return true;
}
}
CommandWrapper commandWrapper;
if (keyTable.TryGetValue(keyPressed, out commandWrapper)) {
if (commandWrapper.CommandID == MenuCommands.Delete) {
// Check Delete menu is enabled.
if (!formDesigner.EnableDelete) {
return false;
}
}
LoggingService.Debug("Run menu command: " + commandWrapper.CommandID);
IMenuCommandService menuCommandService = (IMenuCommandService)formDesigner.Host.GetService(typeof(IMenuCommandService));
ISelectionService selectionService = (ISelectionService)formDesigner.Host.GetService(typeof(ISelectionService));
ICollection components = selectionService.GetSelectedComponents();
if (components.Count == 1) {
foreach (IComponent component in components) {
if (HandleMenuCommand(formDesigner, component, keyPressed))
return false;
}
}
menuCommandService.GlobalInvoke(commandWrapper.CommandID);
if (commandWrapper.RestoreSelection) {
selectionService.SetSelectedComponents(components);
}
return true;
}
return false;
}
bool HandleMenuCommand(FormsDesignerViewContent formDesigner, IComponent activeComponent, Keys keyPressed)
{
Assembly asm = typeof(WindowsFormsDesignerOptionService).Assembly;
// Microsoft made ToolStripKeyboardHandlingService internal, so we need Reflection
Type keyboardType = asm.GetType("System.Windows.Forms.Design.ToolStripKeyboardHandlingService");
object keyboardService = formDesigner.Host.GetService(keyboardType);
if (keyboardService == null) {
LoggingService.Debug("no ToolStripKeyboardHandlingService found");
return false; // handle command normally
}
if (activeComponent is ToolStripItem) {
if (keyPressed == Keys.Up) {
keyboardType.InvokeMember("ProcessUpDown",
BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.InvokeMethod,
null, keyboardService, new object[] { false });
return true; // command was handled specially
} else if (keyPressed == Keys.Down) {
keyboardType.InvokeMember("ProcessUpDown",
BindingFlags.Instance
| BindingFlags.Public
| BindingFlags.InvokeMethod,
null, keyboardService, new object[] { true });
return true; // command was handled specially
}
}
bool active = (bool)keyboardType.InvokeMember("TemplateNodeActive",
BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.GetProperty,
null, keyboardService, null);
if (active) {
return true; // command will handled specially by the text box, don't invoke the CommandID
}
return false; // invoke the CommandID
}
sealed class CommandWrapper
{
CommandID commandID;
bool restoreSelection;
public CommandID CommandID {
get {
return commandID;
}
}
public bool RestoreSelection {
get {
return restoreSelection;
}
}
public CommandWrapper(CommandID commandID) : this(commandID, false)
{
}
public CommandWrapper(CommandID commandID, bool restoreSelection)
{
this.commandID = commandID;
this.restoreSelection = restoreSelection;
}
}
}
}