mwkeycmds.pas

来自「本人买的<<VC++项目开发实例>>源代码配套光盘.」· PAS 代码 · 共 714 行 · 第 1/2 页

PAS
714
字号
{
  Version:      0.89 (see VERSION.RTF for version history)
  Last change:  1999-11-07

  Thanks to: Brad Stowers, Hideo Koiso, Willo van der Merwe
}

unit mwKeyCmds;

{$I MWEDIT.INC}

interface

uses
  Classes, Menus, SysUtils;

const
  //****************************************************************************
  // NOTE!  If you add an editor command, you must also update the
  //    EditorCommandStrs constant array in implementation section below, or the
  //    command will not show up in the IDE.
  //****************************************************************************

  // "Editor Commands".  Key strokes are translated from a table into these
  // I used constants instead of a set so that additional commands could be
  // added in descendants (you can't extend a set)
  ecNone            = 0;    // Nothing.  Useful for user event to handle command

  ecLeft            = 1;    // Move cursor left one char
  ecRight           = 2;    // Move cursor right one char
  ecUp              = 3;    // Move cursor up one line
  ecDown            = 4;    // Move cursor down one line
  ecWordLeft        = 5;    // Move cursor left one word
  ecWordRight       = 6;    // Move cursor right one word
  ecLineStart       = 7;    // Move cursor to beginning of line
  ecLineEnd         = 8;    // Move cursor to end of line
  ecPageUp          = 9;    // Move cursor up one page
  ecPageDown        = 10;   // Move cursor down one page
  ecPageLeft        = 11;   // Move cursor right one page
  ecPageRight       = 12;   // Move cursor left one page
  ecPageTop         = 13;   // Move cursor to top of page
  ecPageBottom      = 14;   // Move cursor to bottom of page
  ecEditorTop       = 15;   // Move cursor to absolute beginning
  ecEditorBottom    = 16;   // Move cursor to absolute end
  ecGotoXY          = 17;   // Move cursor to specific coordinates, Data = PPoint

//******************************************************************************
// Maybe the command processor should just take a boolean that signifies if
// selection is affected or not?
//******************************************************************************

  ecSelection       = 100;  // Add this to ecXXX command to get equivalent
                            // command, but with selection enabled. This is not
                            // a command itself.
  // Same as commands above, except they affect selection, too
  ecSelLeft         = ecLeft + ecSelection;
  ecSelRight        = ecRight + ecSelection;
  ecSelUp           = ecUp + ecSelection;
  ecSelDown         = ecDown + ecSelection;
  ecSelWordLeft     = ecWordLeft + ecSelection;
  ecSelWordRight    = ecWordRight + ecSelection;
  ecSelLineStart    = ecLineStart + ecSelection;
  ecSelLineEnd      = ecLineEnd + ecSelection;
  ecSelPageUp       = ecPageUp + ecSelection;
  ecSelPageDown     = ecPageDown + ecSelection;
  ecSelPageLeft     = ecPageLeft + ecSelection;
  ecSelPageRight    = ecPageRight + ecSelection;
  ecSelPageTop      = ecPageTop + ecSelection;
  ecSelPageBottom   = ecPageBottom + ecSelection;
  ecSelEditorTop    = ecEditorTop + ecSelection;
  ecSelEditorBottom = ecEditorBottom + ecSelection;
  ecSelGotoXY       = ecGotoXY + ecSelection;  // Data = PPoint

  ecSelectAll       = 199;  // Select entire contents of editor, cursor to end

  ecDeleteLastChar  = 401;  // Delete last char (i.e. backspace key)
  ecDeleteChar      = 402;  // Delete char at cursor (i.e. delete key)
  ecDeleteWord      = 403;  // Delete from cursor to end of word
  ecDeleteLastWord  = 404;  // Delete from cursor to start of word
  ecDeleteBOL       = 405;  // Delete from cursor to beginning of line
  ecDeleteEOL       = 406;  // Delete from cursor to end of line
  ecDeleteLine      = 407;  // Delete current line
  ecClearAll        = 408;  // Delete everything
  ecLineBreak       = 409;  // Break line at current position, move caret to new line
  ecInsertLine      = 410;  // Break line at current position, leave caret
  ecChar            = 411;  // Insert a character at current position

  ecImeStr          = 500;  // Insert character(s) from IME

  ecUndo            = 601;  // Perform undo if available
  ecRedo            = 602;  // Perform redo if available
  ecCut             = 603;  // Cut selection to clipboard
  ecCopy            = 604;  // Copy selection to clipboard
  ecPaste           = 605;  // Paste clipboard to current position
  ecScrollUp        = 606;  // Scroll up one line leaving cursor position unchanged.
  ecScrollDown      = 607;  // Scroll down one line leaving cursor position unchanged.
  ecScrollLeft      = 608;  // Scroll left one char leaving cursor position unchanged.
  ecScrollRight     = 609;  // Scroll right one char leaving cursor position unchanged.
  ecInsertMode      = 610;  // Set insert mode
  ecOverwriteMode   = 611;  // Set overwrite mode
  ecToggleMode      = 612;  // Toggle ins/ovr mode
  ecBlockIndent     = 613;  // Indent selection
  ecBlockUnindent   = 614;  // Unindent selection
  ecNormalSelect    = 615;  // Normal selection mode
  ecColumnSelect    = 616;  // Column selection mode
  ecLineSelect      = 617;  // Line selection mode

  ecGotoMarker0     = 701;  // Goto marker
  ecGotoMarker1     = 702;  // Goto marker
  ecGotoMarker2     = 703;  // Goto marker
  ecGotoMarker3     = 704;  // Goto marker
  ecGotoMarker4     = 705;  // Goto marker
  ecGotoMarker5     = 706;  // Goto marker
  ecGotoMarker6     = 707;  // Goto marker
  ecGotoMarker7     = 708;  // Goto marker
  ecGotoMarker8     = 709;  // Goto marker
  ecGotoMarker9     = 710;  // Goto marker
  ecSetMarker0      = 751;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker1      = 752;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker2      = 753;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker3      = 754;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker4      = 755;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker5      = 756;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker6      = 757;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker7      = 758;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker8      = 759;  // Set marker, Data = PPoint - X, Y Pos
  ecSetMarker9      = 760;  // Set marker, Data = PPoint - X, Y Pos

  ecUserFirst       = 1001; // Start of user-defined commands

type
  EmwKeyError = class(Exception);

  TmwEditorCommand = type word;

  TmwKeyStroke = class(TCollectionItem)
  private
    FKey: word;          // Virtual keycode, i.e. VK_xxx
    FShift: TShiftState;

    FKey2: word;
    FShift2: TShiftState;

    FCommand: TmwEditorCommand;
    procedure SetKey(const Value: word);
    procedure SetShift(const Value: TShiftState);
    function GetShortCut: TShortCut;
    procedure SetShortCut(const Value: TShortCut);

    procedure SetKey2(const Value: word);
    procedure SetShift2(const Value: TShiftState);
    function GetShortCut2: TShortCut;
    procedure SetShortCut2(const Value: TShortCut);

    procedure SetCommand(const Value: TmwEditorCommand);
  protected
    {$IFDEF MWE_COMPILER_3_UP}
    function GetDisplayName: string; override;
    {$ENDIF}
  public
    procedure Assign(Source: TPersistent); override;

    // No duplicate checking is done if assignment made via these properties!
    property Key: word
       read FKey write SetKey;
    property Shift: TShiftState
       read FShift write SetShift;

    property Key2: word
       read FKey2 write SetKey2;
    property Shift2: TShiftState
       read FShift2 write SetShift2;

  published
    property ShortCut: TShortCut
       read GetShortCut write SetShortCut;

    property ShortCut2: TShortCut
       read GetShortCut2 write SetShortCut2;

    property Command: TmwEditorCommand
       read FCommand write SetCommand;
  end;

  TmwKeyStrokes = class(TCollection)
  private
    FOwner: TPersistent;
    function GetItem(Index: Integer): TmwKeyStroke;
    procedure SetItem(Index: Integer; Value: TmwKeyStroke);
  protected
    {$IFDEF MWE_COMPILER_3_UP}
    function GetOwner: TPersistent; override;
    {$ENDIF}
  public
    constructor Create(AOwner: TPersistent);
    function Add: TmwKeyStroke;
    procedure Assign(Source: TPersistent); override;
    function FindCommand(Cmd: TmwEditorCommand): integer;
    function FindShortcut(SC: TShortcut): integer;
    function FindKeycode(Code: word; SS: TShiftState): integer;

    function FindShortcut2(SC, SC2: TShortcut): integer;
    function FindKeycode2(Code1: word; SS1: TShiftState;
                          Code2: word; SS2: TShiftState): integer;

    procedure ResetDefaults;

    property Items[Index: Integer]: TmwKeyStroke
       read GetItem write SetItem; default;
  end;

// These are mainly for the TmwEditorCommand property editor, but could be
// useful elsewhere.
function EditorCommandToDescrString(Cmd: TmwEditorCommand): string;
function EditorCommandToCodeString(Cmd: TmwEditorCommand): string;
procedure GetEditorCommandValues(Proc: TGetStrProc);
function IdentToEditorCommand(const Ident: string; var Cmd: longint): boolean;
function EditorCommandToIdent(Cmd: longint; var Ident: string): boolean;

implementation

uses
  Windows, mwLocalStr;

{ Command mapping routines }

{$IFDEF MWE_COMPILER_2}
// This is defined in D3/C3 and up.
type
  TIdentMapEntry = record
    Value: TmwEditorCommand;
    Name: string;
  end;
{$ENDIF}

const
  EditorCommandStrs: array[0..85] of TIdentMapEntry = (
    (Value: ecNone; Name: 'ecNone'),
    (Value: ecLeft; Name: 'ecLeft'),
    (Value: ecRight; Name: 'ecRight'),
    (Value: ecUp; Name: 'ecUp'),
    (Value: ecDown; Name: 'ecDown'),
    (Value: ecWordLeft; Name: 'ecWordLeft'),
    (Value: ecWordRight; Name: 'ecWordRight'),
    (Value: ecLineStart; Name: 'ecLineStart'),
    (Value: ecLineEnd; Name: 'ecLineEnd'),
    (Value: ecPageUp; Name: 'ecPageUp'),
    (Value: ecPageDown; Name: 'ecPageDown'),
    (Value: ecPageLeft; Name: 'ecPageLeft'),
    (Value: ecPageRight; Name: 'ecPageRight'),
    (Value: ecPageTop; Name: 'ecPageTop'),
    (Value: ecPageBottom; Name: 'ecPageBottom'),
    (Value: ecEditorTop; Name: 'ecEditorTop'),
    (Value: ecEditorBottom; Name: 'ecEditorBottom'),
    (Value: ecGotoXY; Name: 'ecGotoXY'),
    (Value: ecSelLeft; Name: 'ecSelLeft'),
    (Value: ecSelRight; Name: 'ecSelRight'),
    (Value: ecSelUp; Name: 'ecSelUp'),
    (Value: ecSelDown; Name: 'ecSelDown'),
    (Value: ecSelWordLeft; Name: 'ecSelWordLeft'),
    (Value: ecSelWordRight; Name: 'ecSelWordRight'),
    (Value: ecSelLineStart; Name: 'ecSelLineStart'),
    (Value: ecSelLineEnd; Name: 'ecSelLineEnd'),
    (Value: ecSelPageUp; Name: 'ecSelPageUp'),
    (Value: ecSelPageDown; Name: 'ecSelPageDown'),
    (Value: ecSelPageLeft; Name: 'ecSelPageLeft'),
    (Value: ecSelPageRight; Name: 'ecSelPageRight'),
    (Value: ecSelPageTop; Name: 'ecSelPageTop'),
    (Value: ecSelPageBottom; Name: 'ecSelPageBottom'),
    (Value: ecSelEditorTop; Name: 'ecSelEditorTop'),
    (Value: ecSelEditorBottom; Name: 'ecSelEditorBottom'),
    (Value: ecSelGotoXY; Name: 'ecSelGotoXY'),
    (Value: ecSelectAll; Name: 'ecSelectAll'),
    (Value: ecDeleteLastChar; Name: 'ecDeleteLastChar'),
    (Value: ecDeleteChar; Name: 'ecDeleteChar'),
    (Value: ecDeleteWord; Name: 'ecDeleteWord'),
    (Value: ecDeleteLastWord; Name: 'ecDeleteLastWord'),
    (Value: ecDeleteBOL; Name: 'ecDeleteBOL'),
    (Value: ecDeleteEOL; Name: 'ecDeleteEOL'),
    (Value: ecDeleteLine; Name: 'ecDeleteLine'),
    (Value: ecClearAll; Name: 'ecClearAll'),
    (Value: ecLineBreak; Name: 'ecLineBreak'),
    (Value: ecInsertLine; Name: 'ecInsertLine'),
    (Value: ecChar; Name: 'ecChar'),
    (Value: ecImeStr; Name: 'ecImeStr'),
    (Value: ecUndo; Name: 'ecUndo'),
    (Value: ecRedo; Name: 'ecRedo'),
    (Value: ecCut; Name: 'ecCut'),
    (Value: ecCopy; Name: 'ecCopy'),
    (Value: ecPaste; Name: 'ecPaste'),
    (Value: ecScrollUp; Name: 'ecScrollUp'),
    (Value: ecScrollDown; Name: 'ecScrollDown'),
    (Value: ecScrollLeft; Name: 'ecScrollLeft'),
    (Value: ecScrollRight; Name: 'ecScrollRight'),
    (Value: ecInsertMode; Name: 'ecInsertMode'),
    (Value: ecOverwriteMode; Name: 'ecOverwriteMode'),
    (Value: ecToggleMode; Name: 'ecToggleMode'),
    (Value: ecBlockIndent; Name: 'ecBlockIndent'),
    (Value: ecBlockUnindent; Name: 'ecBlockUnindent'),
    (Value: ecNormalSelect; Name: 'ecNormalSelect'),
    (Value: ecColumnSelect; Name: 'ecColumnSelect'),
    (Value: ecLineSelect; Name: 'ecLineSelect'),
    (Value: ecUserFirst; Name: 'ecUserFirst'),
    (Value: ecGotoMarker0; Name: 'ecGotoMarker0'),
    (Value: ecGotoMarker1; Name: 'ecGotoMarker1'),
    (Value: ecGotoMarker2; Name: 'ecGotoMarker2'),
    (Value: ecGotoMarker3; Name: 'ecGotoMarker3'),
    (Value: ecGotoMarker4; Name: 'ecGotoMarker4'),
    (Value: ecGotoMarker5; Name: 'ecGotoMarker5'),
    (Value: ecGotoMarker6; Name: 'ecGotoMarker6'),
    (Value: ecGotoMarker7; Name: 'ecGotoMarker7'),
    (Value: ecGotoMarker8; Name: 'ecGotoMarker8'),
    (Value: ecGotoMarker9; Name: 'ecGotoMarker9'),
    (Value: ecSetMarker0; Name: 'ecSetMarker0'),
    (Value: ecSetMarker1; Name: 'ecSetMarker1'),
    (Value: ecSetMarker2; Name: 'ecSetMarker2'),
    (Value: ecSetMarker3; Name: 'ecSetMarker3'),
    (Value: ecSetMarker4; Name: 'ecSetMarker4'),
    (Value: ecSetMarker5; Name: 'ecSetMarker5'),
    (Value: ecSetMarker6; Name: 'ecSetMarker6'),
    (Value: ecSetMarker7; Name: 'ecSetMarker7'),
    (Value: ecSetMarker8; Name: 'ecSetMarker8'),
    (Value: ecSetMarker9; Name: 'ecSetMarker9'));

procedure GetEditorCommandValues(Proc: TGetStrProc);
var
  i: integer;
begin
  for i := Low(EditorCommandStrs) to High(EditorCommandStrs) do
    Proc(EditorCommandStrs[I].Name);
end;

function IdentToEditorCommand(const Ident: string; var Cmd: longint): boolean;
{$IFDEF MWE_COMPILER_2}
var
  I: Integer;
{$ENDIF}
begin
  {$IFDEF MWE_COMPILER_2}
  Result := FALSE;
  for I := Low(EditorCommandStrs) to High(EditorCommandStrs) do
    if CompareText(EditorCommandStrs[I].Name, Ident) = 0 then
    begin
      Result := TRUE;
      Cmd := EditorCommandStrs[I].Value;
      break;
    end;

  {$ELSE}

    Result := IdentToInt(Ident, Cmd, EditorCommandStrs);
  {$ENDIF}
end;

function EditorCommandToIdent(Cmd: longint; var Ident: string): boolean;
{$IFDEF MWE_COMPILER_2}
var

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?