📄 jvcommandedit.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvCmdEdit.PAS, released on 2002-05-26.
The Initial Developer of the Original Code is Peter Th鰎nqvist [peter3 att users dott sourceforge dott net]
Portions created by Peter Th鰎nqvist are Copyright (C) 2002 Peter Th鰎nqvist.
All Rights Reserved.
Contributor(s):
Last Modified: 2002-05-26
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
{$I JVCL.INC}
{A TEdit that displays and reacts to command input. }
unit JvCommandEdit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Menus,
JvEdit, JvComponent, JvTypes;
type
TJvCmdEvent = procedure(Sender: TObject; Cmd: Integer; Params: TStrings; var Handled: Boolean) of object;
TJvCustomCommandEdit = class(TJvCustomEdit)
private
FShift: TShiftState;
FKey: Word;
FSuppress: Boolean;
FCurrCmd: string;
FCurrCmdIndex: Integer;
FPrompt: string;
FOnCommand: TJvCmdEvent;
FExecuteKey: TShortCut;
FHistory: TStrings;
FCommands: TStrings;
FArrowKeys: Boolean;
procedure WMPaste(var Msg: TWMPaste); message WM_PASTE;
procedure WMCopy(var Msg: TWMCopy); message WM_COPY;
procedure WMCut(var Msg: TWMCut); message WM_CUT;
procedure SetCommands(const Value: TStrings);
procedure SetCurrCmd(const Value: string);
procedure SetExecuteKey(const Value: TShortCut);
procedure SetHistory(const Value: TStrings);
procedure SetPrompt(const Value: string);
procedure CheckLimits(var Key: Word);
procedure ResetHistory;
// procedure UpdateState;
function GetCurrCmd: string;
procedure SetArrowKeys(const Value: Boolean);
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure KeyUp(var Key: Word; Shift: TShiftState); override;
procedure KeyPress(var Key: Char); override;
function DoCommand(Cmd: Integer; Params: TStrings): Boolean; virtual;
property CurrCmd: string read GetCurrCmd write SetCurrCmd;
property Prompt: string read FPrompt write SetPrompt;
property History: TStrings read FHistory write SetHistory;
property Commands: TStrings read FCommands write SetCommands;
property ExecuteKey: TShortCut read FExecuteKey write SetExecuteKey default VK_RETURN;
property OnCommand: TJvCmdEvent read FOnCommand write FOnCommand;
property ArrowKeys: Boolean read FArrowKeys write SetArrowKeys default True;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GotoCmd(Index: Integer; RelToCurr: Boolean): Boolean;
function Execute: Boolean;
function ExecuteCommand(const Cmd: string): Boolean;
end;
TJvCommandEdit = class(TJvCustomCommandEdit)
published
property CurrCmd;
property ClipboardCommands;
property Commands;
property ExecuteKey;
property History;
property Prompt;
property OnCommand;
property ArrowKeys;
property Align;
property AutoSelect;
property AutoSize;
property BorderStyle;
property CharCase;
property Color;
property Ctl3D;
property DragCursor;
property DragMode;
property Enabled;
property Font;
property HideSelection;
property ImeMode;
property ImeName;
property MaxLength;
property OEMConvert;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnChange;
property OnClick;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnStartDrag;
property Anchors;
property BiDiMode;
property Constraints;
property DragKind;
property ParentBiDiMode;
property OnEndDock;
property OnStartDock;
end;
implementation
// uses
// utilsString;
constructor TJvCustomCommandEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FHistory := TStringList.Create;
FCommands := TStringList.Create;
FArrowKeys := True;
FExecuteKey := VK_RETURN;
ShortCutToKey(FExecuteKey, FKey, FShift);
FCurrCmd := '';
Prompt := ':';
end;
destructor TJvCustomCommandEdit.Destroy;
begin
FHistory.Free;
FCommands.Free;
inherited Destroy;
end;
{
procedure TJvCustomCommandEdit.UpdateState;
begin
Text := FPrompt;
FSuppress := False;
if CanFocus and HasParent then
SelStart := length(FPrompt);
end;
}
procedure TJvCustomCommandEdit.CheckLimits(var Key: Word);
var
P: TPoint;
begin
if SelStart < Length(FPrompt) then
begin
Key := 0;
P.X := SelStart + SelLength;
P.Y := Length(FPrompt);
SendMessage(Handle, EM_SETSEL, P.X, P.Y);
SendMessage(Handle, EM_SCROLLCARET, 0, 0);
end;
end;
procedure TJvCustomCommandEdit.ResetHistory;
begin
FHistory.Clear;
FCurrCmdIndex := 0;
end;
{$IFOPT J-}
{$DEFINE RESETJ}
{$ENDIF}
{$J+}
function strtok(Search, Delim: string): string;
const
I: Integer = 1;
Len: Integer = 0;
PrvStr: string = '';
begin
Result := '';
if Search <> '' then
begin
I := 1;
PrvStr := Search;
Len := Length(PrvStr);
end;
if PrvStr = '' then
Exit;
while (I <= Len) and (Pos(PrvStr[I], Delim) > 0) do
Inc(I);
while (I <= Len) and (Pos(PrvStr[I], Delim) = 0) do
begin
Result := Result + PrvStr[I];
Inc(I);
end;
end;
{$IFDEF RESETJ}
{$UNDEF RESETJ}
{$J-}
{$ENDIF}
function TJvCustomCommandEdit.Execute: Boolean;
var
Params: TStringList;
Cmd: string;
begin
FCurrCmd := Copy(Text, Length(Prompt) + 1, MaxInt);
Cmd := FCurrCmd;
Cmd := strtok(Cmd, ' ');
Params := TStringList.Create;
try
while Cmd <> '' do
begin
Params.Add(Cmd);
Cmd := strtok('', ' ');
end;
if Params.Count > 0 then
begin
Cmd := Params[0];
Params.Delete(0);
end
else
Cmd := '';
Result := DoCommand(FCommands.IndexOf(Cmd), Params);
if Result then
begin
FHistory.Add(CurrCmd);
FCurrCmdIndex := FHistory.Count - 1;
end;
finally
Params.Free;
end;
// UpdateState;
end;
function TJvCustomCommandEdit.GotoCmd(Index: Integer;
RelToCurr: Boolean): Boolean;
begin
Result := False;
if RelToCurr then
Inc(FCurrCmdIndex, Index)
else
FCurrCmdIndex := Index;
if FCurrCmdIndex < 0 then
FCurrCmdIndex := 0;
if FCurrCmdIndex >= FHistory.Count then
FCurrCmdIndex := FHistory.Count - 1;
Index := FCurrCmdIndex;
if (Index > -1) and (Index < FHistory.Count) then
begin
CurrCmd := History[Index];
Result := True;
SelStart := Length(Text) + 1;
end
else
Beep;
end;
procedure TJvCustomCommandEdit.KeyPress(var Key: Char);
begin
if FSuppress {and (Key = Char(FKey))} then
Key := #0
else
begin
// CheckLimits(Char(Key));
ReadOnly := (SelStart < Length(Prompt)) or ((SelStart <= Length(Prompt)) and (Key = #8));
end;
inherited KeyPress(Key);
FSuppress := False;
end;
procedure TJvCustomCommandEdit.KeyDown(var Key: Word; Shift: TShiftState);
begin
CheckLimits(Key);
ReadOnly := (SelStart < Length(Prompt)) or ((SelStart <= Length(Prompt)) and (Key = VK_BACK));
if (FArrowKeys and (Shift = []) and (Key in [VK_UP, VK_DOWN, VK_F3, VK_ESCAPE])) or
((Key = FKey) and (FShift = Shift)) or ((Key = VK_LEFT) and (SelStart + SelLength <= Length(Prompt))) then
begin
// FSuppress := True;
Key := 0;
end;
inherited KeyDown(Key, Shift);
end;
procedure TJvCustomCommandEdit.KeyUp(var Key: Word; Shift: TShiftState);
var
K2: Word;
begin
CheckLimits(Key);
K2 := Key;
Key := 0;
ReadOnly := (SelStart + SelLength < Length(Prompt)) or ((SelStart + SelLength <= Length(Prompt)) and (Key = VK_BACK));
if (K2 = FKey) and (FShift = Shift) then
Execute
else
if FArrowKeys and (Shift = []) then
begin
FSuppress := True;
case K2 of
VK_UP:
GotoCmd(-1, True);
VK_DOWN:
GotoCmd(1, True);
VK_F3:
GotoCmd(FHistory.Count - 1, False);
VK_ESCAPE:
CurrCmd := '';
else
begin
Key := K2;
FSuppress := False;
inherited KeyUp(Key, Shift);
end
end
end
else
begin
FSuppress := False;
Key := K2;
inherited KeyUp(Key, Shift);
end;
end;
procedure TJvCustomCommandEdit.SetCommands(const Value: TStrings);
begin
FCommands.Assign(Value);
ResetHistory;
end;
procedure TJvCustomCommandEdit.SetCurrCmd(const Value: string);
begin
FCurrCmd := Value;
Text := FPrompt + FCurrCmd;
if CanFocus and HasParent then
SelStart := Length(Prompt) + 1;
end;
procedure TJvCustomCommandEdit.SetExecuteKey(const Value: TShortCut);
begin
if FExecuteKey <> Value then
begin
FExecuteKey := Value;
ShortCutToKey(FExecuteKey, FKey, FShift);
end;
end;
procedure TJvCustomCommandEdit.SetHistory(const Value: TStrings);
begin
FHistory.Assign(Value);
end;
procedure TJvCustomCommandEdit.SetPrompt(const Value: string);
begin
FPrompt := Value;
Text := FPrompt + CurrCmd;
end;
procedure TJvCustomCommandEdit.WMCopy(var Msg: TWMCopy);
var
Key: Word;
begin
if caCopy in ClipboardCommands then
begin
Key := 0;
CheckLimits(Key);
inherited;
end;
end;
procedure TJvCustomCommandEdit.WMCut(var Msg: TWMCut);
var
Key: Word;
begin
if caCut in ClipboardCommands then
begin
Key := 0;
CheckLimits(Key);
inherited;
end;
end;
procedure TJvCustomCommandEdit.WMPaste(var Msg: TWMPaste);
var
Key: Word;
begin
if caPaste in ClipboardCommands then
begin
Key := 0;
CheckLimits(Key);
inherited;
end;
end;
function TJvCustomCommandEdit.DoCommand(Cmd: Integer; Params: TStrings): Boolean;
begin
Result := True;
// FSuppress := True;
if Assigned(FOnCommand) then
FOnCommand(Self, Cmd, Params, Result);
end;
procedure TJvCustomCommandEdit.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Key: Word;
begin
inherited MouseDown(Button, Shift, X, y);
CheckLimits(Key);
end;
procedure TJvCustomCommandEdit.MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
Key: Word;
begin
inherited MouseUp(Button, Shift, X, Y);
CheckLimits(Key);
end;
function TJvCustomCommandEdit.GetCurrCmd: string;
begin
Result := Copy(Text, Length(FPrompt) + 1, MaxInt);
end;
procedure TJvCustomCommandEdit.SetArrowKeys(const Value: Boolean);
begin
if FArrowKeys <> Value then
FArrowKeys := Value;
end;
function TJvCustomCommandEdit.ExecuteCommand(const Cmd: string): Boolean;
begin
CurrCmd := Cmd;
Result := Execute;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -