Download KeyboardSupportDemo.zip version 1.0.0.0, last updated 04/06/2016 (10.17 KB)

Download
  • md5: 90e557815ee49f581745ed334ea2d9ed
  • sha1: 3fbc13752142394a4c4dcab84de6ffce94de3b4f
  • sha256: eb014fe61a006edcbe89107bc437dd99b3910badf471f20dc30d79fd7edbc743
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

// Adding keyboard accelerators and visual cues to a WinForms control
// http://www.cyotek.com/blog/adding-keyboard-accelerators-and-visual-cues-to-a-winforms-control
// Copyright 2016 Cyotek Ltd. All Rights Reserved.
//
//  If find this code useful, attribution, donations or contributions are welcome.

namespace Cyotek.Articles.KeyboardSupport
{
  internal sealed class Button : Control, IButtonControl
  {
    #region Constants

    private const TextFormatFlags _defaultFlags = TextFormatFlags.NoPadding | TextFormatFlags.SingleLine | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis;

    #endregion

    #region Fields

    private bool _isDefault;

    private ButtonState _state;

    #endregion

    #region Constructors

    public Button()
    {
      this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
      this.SetStyle(ControlStyles.StandardDoubleClick, false);
      _state = ButtonState.Normal;
    }

    #endregion

    #region Events

    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public new event EventHandler DoubleClick
    {
      add { base.DoubleClick += value; }
      remove { base.DoubleClick -= value; }
    }

    [Browsable(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    public new event MouseEventHandler MouseDoubleClick
    {
      add { base.MouseDoubleClick += value; }
      remove { base.MouseDoubleClick -= value; }
    }

    #endregion

    #region Methods

    protected override void OnBackColorChanged(EventArgs e)
    {
      base.OnBackColorChanged(e);

      this.Invalidate();
    }

    protected override void OnEnabledChanged(EventArgs e)
    {
      base.OnEnabledChanged(e);

      this.SetState(this.Enabled ? ButtonState.Normal : ButtonState.Inactive);
    }

    protected override void OnFontChanged(EventArgs e)
    {
      base.OnFontChanged(e);

      this.Invalidate();
    }

    protected override void OnForeColorChanged(EventArgs e)
    {
      base.OnForeColorChanged(e);

      this.Invalidate();
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
      base.OnKeyDown(e);

      if (e.KeyCode == Keys.Space && e.Modifiers == Keys.None)
      {
        this.SetState(ButtonState.Pushed);
      }
    }

    protected override void OnKeyUp(KeyEventArgs e)
    {
      base.OnKeyUp(e);

      if ((e.KeyCode & Keys.Space) == Keys.Space)
      {
        this.SetState(ButtonState.Normal);

        this.PerformClick();
      }
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
      base.OnMouseDown(e);

      if (this.CanFocus)
      {
        this.Focus();
      }

      this.SetState(ButtonState.Pushed);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
      base.OnMouseUp(e);

      this.SetState(ButtonState.Normal);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
      Graphics g;

      base.OnPaint(e);

      g = e.Graphics;

      this.PaintButton(g);
      this.PaintText(g);
    }

    protected override void OnTextChanged(EventArgs e)
    {
      base.OnTextChanged(e);

      this.Invalidate();
    }

    protected override bool ProcessMnemonic(char charCode)
    {
      bool processed;

      processed = this.CanFocus && IsMnemonic(charCode, this.Text);

      if (processed)
      {
        this.Focus();
        this.PerformClick();
      }

      return processed;
    }

    private void PaintButton(Graphics g)
    {
      Rectangle bounds;

      bounds = this.ClientRectangle;

      if (_isDefault)
      {
        g.DrawRectangle(SystemPens.WindowFrame, bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
        bounds.Inflate(-1, -1);
      }

      ControlPaint.DrawButton(g, bounds, _state);

      if (this.ShowFocusCues && this.Focused)
      {
        bounds.Inflate(-3, -3);

        ControlPaint.DrawFocusRectangle(g, bounds);
      }
    }

    private void PaintText(Graphics g)
    {
      Color textColor;
      Rectangle textBounds;
      TextFormatFlags flags;
      Size size;

      size = this.ClientSize;
      textColor = this.Enabled ? this.ForeColor : SystemColors.GrayText;
      textBounds = new Rectangle(3, 3, size.Width - 6, size.Height - 6);

      if (_state == ButtonState.Pushed)
      {
        textBounds.X++;
        textBounds.Y++;
      }

      flags = _defaultFlags;
      if (!this.ShowKeyboardCues)
      {
        flags |= TextFormatFlags.HidePrefix;
      }

      TextRenderer.DrawText(g, this.Text, this.Font, textBounds, textColor, flags);
    }

    private void SetState(ButtonState state)
    {
      _state = state;

      this.Invalidate();
    }

    #endregion

    #region IButtonControl Interface

    public void NotifyDefault(bool value)
    {
      _isDefault = value;

      this.Invalidate();
    }

    public void PerformClick()
    {
      this.OnClick(EventArgs.Empty);
      ;
    }

    [Category("Behavior")]
    [DefaultValue(typeof(DialogResult), "None")]
    public DialogResult DialogResult { get; set; }

    #endregion
  }
}

Donate

Donate