{******************************************************************************}
{                       CnPack For Delphi/C++Builder                           }
{                     中国人自己的开放源码第三方开发包                         }
{                   (C)Copyright 2001-2025 CnPack 开发组                       }
{                   ------------------------------------                       }
{                                                                              }
{            本开发包是开源的自由软件，您可以遵照 CnPack 的发布协议来修        }
{        改和重新发布这一程序。                                                }
{                                                                              }
{            发布这一开发包的目的是希望它有用，但没有任何担保。甚至没有        }
{        适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。        }
{                                                                              }
{            您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果        }
{        还没有，可访问我们的网站：                                            }
{                                                                              }
{            网站地址：http://www.cnpack.org                                   }
{            电子邮件：master@cnpack.org                                       }
{                                                                              }
{******************************************************************************}

unit CnWizShortCut;
{* |<PRE>
================================================================================
* 软件名称：CnPack IDE 专家包
* 单元名称：IDE 快捷键定义和管理器实现单元
* 单元作者：周劲羽 (zjy@cnpack.org)
* 开发平台：PWin2000Pro + Delphi 5.01
* 兼容测试：PWin9X/2000/XP + Delphi 5/6/7 + C++Builder 5/6
* 本 地 化：该单元中的字符串均符合本地化处理方式
* 修改记录：2017.05.18 V1.0
*               创建单元，实现功能
================================================================================
|</PRE>}

interface

uses
  Windows, Messages, Classes, SysUtils, Menus, ExtCtrls, ToolsAPI,
  CnWizConsts, CnCommon;

type
//==============================================================================
// IDE 快捷键定义类
//==============================================================================

{ TCnWizShortCut }

  TCnWizShortCutMgr = class;

  TCnWizShortCut = class(TObject)
  {* IDE 快捷键定义类，在 CnWizards 中使用，定义了快捷键的属性和功能。
     每一个已命名的快捷键实例，会自动在创建时从注册表加载快捷键，并在释放时
     进行保存。请不要直接创建和释放该类的实例，而应该使用快捷键管理器
     WizShortCutMgr 的 Add 和 Delete 方法来实现。}
  private
    FDefShortCut: TShortCut;
    FOwner: TCnWizShortCutMgr;
    FShortCut: TShortCut;
    FKeyProc: TNotifyEvent;
    FMenuName: string;
    FName: string;
    FTag: Integer;
    procedure SetKeyProc(const Value: TNotifyEvent);
    procedure SetShortCut(const Value: TShortCut);
    procedure SetMenuName(const Value: string);
    function ReadShortCut(const Name: string; DefShortCut: TShortCut): TShortCut;
    procedure WriteShortCut(const Name: string; AShortCut: TShortCut);
  protected
    procedure Changed; virtual;
  public
    constructor Create(AOwner: TCnWizShortCutMgr; const AName: string;
      AShortCut: TShortCut; AKeyProc: TNotifyEvent; const AMenuName: string;
      ATag: Integer = 0);
    {* 类构造器，请不要直接调用该方法创建类实例，而应该用快捷键管理器
       WizShortCutMgr.Add 来创建，并用它的 Delete 来删除。}
    destructor Destroy; override;
    {* 类析构器，请不要直接释放该类的实例，而应该用快捷键管理器
       WizShortCutMgr.Delete 来删除一个 IDE 快捷键。}

    property Name: string read FName;
    {* 快捷键的名字，同时也是保存在注册表中的键值名。如果为空，该快捷键将不
       保存在注册表中。}
    property ShortCut: TShortCut read FShortCut write SetShortCut;
    {* 快捷键键值。}
    property KeyProc: TNotifyEvent read FKeyProc write SetKeyProc;
    {* 快捷键通知事件，当快捷键被按下时调用该事件}
    property MenuName: string read FMenuName write SetMenuName;
    {* 与快捷键关联的 IDE 菜单项的名字}
    property Tag: Integer read FTag write FTag;
    {* 快捷键标签}
  end;

//==============================================================================
// IDE 快捷键绑定接口实现类
//==============================================================================

{ TCnKeyBinding }

  TCnKeyBinding = class(TNotifierObject, IOTAKeyboardBinding)
  {* IDE 快捷键绑定接口实现类，在 CnWizards 中内部使用。
     该类实现了 IOTAKeyboardBinding 接口，可被 IDE 调用以定义 IDE 的快捷键绑定。
     该类仅在 IDE 快捷键管理器类 TCnWizShortCutMgr 内部使用，请不要直接使用。}
  private
    FOwner: TCnWizShortCutMgr;
  protected
    procedure KeyProc(const Context: IOTAKeyContext; KeyCode: TShortcut;
      var BindingResult: TKeyBindingResult);
    property Owner: TCnWizShortCutMgr read FOwner;
  public
    constructor Create(AOwner: TCnWizShortCutMgr);
    {* 类构造器，传递 IDE 快捷键管理器作为参数}
    destructor Destroy; override;

    // IOTAKeyboardBinding methods
    function GetBindingType: TBindingType;
    {* 取绑定类型，必须实现的 IOTAKeyboardBinding 方法}
    function GetDisplayName: string;
    {* 取快捷键绑定显示名称，必须实现的 IOTAKeyboardBinding 方法}
    function GetName: string;
    {* 取快捷键绑定名称，必须实现的 IOTAKeyboardBinding 方法}
    procedure BindKeyboard(const BindingServices: IOTAKeyBindingServices);
    {* 快捷键绑定过程，必须实现的 IOTAKeyboardBinding 方法}
  end;

//==============================================================================
// IDE 快捷键管理器类
//==============================================================================

{ TCnWizShortCutMgr }

  TCnWizShortCutMgr = class(TObject)
  {* IDE 快捷键管理器类，用于维护在 IDE 中绑定的快捷键的列表。
     请不要直接创建该类的实例，应使用 WizShortCutMgr 来获得当前的管理器实例。}
  private
    FShortCuts: TList;
    FKeyBindingIndex: Integer;
    FUpdateCount: Integer;
    FUpdated: Boolean;
    FSaveMenus: TList;
    FSaveShortCuts: TList;
    FMenuTimer: TTimer;
    function GetShortCuts(Index: Integer): TCnWizShortCut;
    function GetCount: Integer;
    procedure InstallKeyBinding;
    procedure RemoveKeyBinding;
    procedure SaveMainMenuShortCuts;
    procedure RestoreMainMenuShortCuts;
    procedure DoRestoreMainMenuShortCuts(Sender: TObject);
  public
    constructor Create;
    {* 类构造器，请不要直接创建该类的实例，应使用 WizShortCutMgr 来获得当前
       的管理器实例。}
    destructor Destroy; override;
    {* 类析构器。}
    function IndexOfShortCut(AWizShortCut: TCnWizShortCut): Integer;
    {* 根据 IDE 快捷键对象查找索引号，参数为快捷键对象，如果不存在返回-1。}
    function IndexOfName(const AName: string): Integer; 
    {* 根据快捷键名称查找索引号，如果不存在返回-1。}
    function Add(const AName: string; AShortCut: TShortCut; AKeyProc:
      TNotifyEvent; const AMenuName: string = ''; ATag: Integer = 0): TCnWizShortCut;
    {* 新增一个快捷键定义
     |<PRE>
       AName: string           - 快捷键名称，如果为空串则该快捷键不保存到注册表中
       AShortCut: TShortCut    - 快捷键默认键值，如果 AName 有效，实际使用的键值是从注册表中读取的
       AKeyProc: TNotifyEvent  - 快捷键通知事件
       AMenuName: string       - 快捷键对应的 IDE 主菜单项命令，如果没有可以为空
       Result: Integer;        - 返回新增加的快捷键索引号，如果要定义的快捷键已存在返回-1
     |</PRE>}
    procedure Delete(Index: Integer);
    {* 删除一个快捷键对象，参数为快捷键对象的索引号。}
    procedure DeleteShortCut(var AWizShortCut: TCnWizShortCut); 
    {* 删除一个快捷键对象，参数为快捷键对象，调用成功后参数将设为 nil。}
    procedure Clear;
    {* 清空快捷键对象列表}
    procedure BeginUpdate;
    {* 开始更新快捷键对象列表，在此之后对快捷键列表的改动将不会自动进行绑定刷新，
       只有当更新结束后才会自动重新绑定。
       使用时必须与 EndUpdate 配对。}
    procedure EndUpdate;
    {* 结束对快捷键对象列表的更新，如果是最后一次调用，将自动重新绑定 IDE 快捷键。
       使用时必须与 BeginUpdate 配对。}
    function Updating: Boolean;
    {* 快捷键对象列表更新状态，见 BeginUpdate 和 EndUpdate}
    procedure UpdateBinding;
    {* 更新已绑定的快捷键对象列表}

    property Count: Integer read GetCount;
    {* 快捷键对象总项数}
    property ShortCuts[Index: Integer]: TCnWizShortCut read GetShortCuts;
    {* 快捷键对象数组}
  end;

function WizShortCutMgr: TCnWizShortCutMgr;
{* 返回当前的 IDE 快捷键管理器实例。如果需要使用快捷键管理器，请不要直接创建
   TCnWizShortCutMgr 的实例，而应该用该函数来访问。}

implementation

{ TCnWizShortCut }

procedure TCnWizShortCut.Changed;
begin

end;

constructor TCnWizShortCut.Create(AOwner: TCnWizShortCutMgr;
  const AName: string; AShortCut: TShortCut; AKeyProc: TNotifyEvent;
  const AMenuName: string; ATag: Integer);
begin

end;

destructor TCnWizShortCut.Destroy;
begin
  inherited;

end;

function TCnWizShortCut.ReadShortCut(const Name: string;
  DefShortCut: TShortCut): TShortCut;
begin

end;

procedure TCnWizShortCut.SetKeyProc(const Value: TNotifyEvent);
begin

end;

procedure TCnWizShortCut.SetMenuName(const Value: string);
begin

end;

procedure TCnWizShortCut.SetShortCut(const Value: TShortCut);
begin

end;

procedure TCnWizShortCut.WriteShortCut(const Name: string;
  AShortCut: TShortCut);
begin

end;

{ TCnWizShortCutMgr }

function TCnWizShortCutMgr.Add(const AName: string; AShortCut: TShortCut;
  AKeyProc: TNotifyEvent; const AMenuName: string;
  ATag: Integer): TCnWizShortCut;
begin

end;

procedure TCnWizShortCutMgr.BeginUpdate;
begin

end;

procedure TCnWizShortCutMgr.Clear;
begin

end;

constructor TCnWizShortCutMgr.Create;
begin

end;

procedure TCnWizShortCutMgr.Delete(Index: Integer);
begin

end;

procedure TCnWizShortCutMgr.DeleteShortCut(
  var AWizShortCut: TCnWizShortCut);
begin

end;

destructor TCnWizShortCutMgr.Destroy;
begin
  inherited;

end;

procedure TCnWizShortCutMgr.DoRestoreMainMenuShortCuts(Sender: TObject);
begin

end;

procedure TCnWizShortCutMgr.EndUpdate;
begin

end;

function TCnWizShortCutMgr.GetCount: Integer;
begin

end;

function TCnWizShortCutMgr.GetShortCuts(Index: Integer): TCnWizShortCut;
begin

end;

function TCnWizShortCutMgr.IndexOfName(const AName: string): Integer;
begin

end;

function TCnWizShortCutMgr.IndexOfShortCut(
  AWizShortCut: TCnWizShortCut): Integer;
begin

end;

procedure TCnWizShortCutMgr.InstallKeyBinding;
begin

end;

procedure TCnWizShortCutMgr.RemoveKeyBinding;
begin

end;

procedure TCnWizShortCutMgr.RestoreMainMenuShortCuts;
begin

end;

procedure TCnWizShortCutMgr.SaveMainMenuShortCuts;
begin

end;

procedure TCnWizShortCutMgr.UpdateBinding;
begin

end;

function TCnWizShortCutMgr.Updating: Boolean;
begin

end;

function WizShortCutMgr: TCnWizShortCutMgr;
begin

end;

{ TCnKeyBinding }

procedure TCnKeyBinding.BindKeyboard(
  const BindingServices: IOTAKeyBindingServices);
begin

end;

constructor TCnKeyBinding.Create(AOwner: TCnWizShortCutMgr);
begin

end;

destructor TCnKeyBinding.Destroy;
begin
  inherited;

end;

function TCnKeyBinding.GetBindingType: TBindingType;
begin

end;

function TCnKeyBinding.GetDisplayName: string;
begin

end;

function TCnKeyBinding.GetName: string;
begin

end;

procedure TCnKeyBinding.KeyProc(const Context: IOTAKeyContext;
  KeyCode: TShortcut; var BindingResult: TKeyBindingResult);
begin

end;

end.
