实现一个热键注册编辑的类

Qt全局热键之使用QxtGlobalShortcut实现 全局热键,我们普遍关心的三个问题 检测快捷键是否被占用 注册(反注册)快捷键 快捷键被触发 目前有两个的多平台(windows、linux和mac平台)上能用较稳定的开源库 QxtGlobalShortcut(Qt5版本是QxtGlobalShortcut5)和QHotkey 本文就介绍QxtGlobalShortcut在Qt5中的应用,看看最简单使用步骤和例子: 三步曲: 首先是下载htt... 阅读详情

实现一个热键注册编辑的类

CST(http://blog.youkuaiyun.com/mrtechno) 2005-8-19

 

 

1 文档目的... 1

2 热键编程基础... 1

2.1 API函数... 1

2.2 编程方法... 2

3 实现概述... 4

4 实现细节... 4

4.1 XML配置文档结构... 4

4.2 热键编辑控件 ThotKeyEdit 5

4.3 热键自定义窗体类TformHotKeyconfig. 6

4.4 主类ThotKeyConfig. 6

4.4.1 解析XML文档... 7

4.4.2 注册注销系统热键... 8

4.4.3 热键编辑窗体... 8

4.4.4 对象唯一性... 8

5 程序源代码... 9

6 小结... 25

6.1 没有解决的一些问题... 25

6.2 程序心得... 26

 

1 文档目的

本文档介绍了在Delphi 7中注册、注销、使用热键(Hot Key)的基本函数和方法,并在此基础上介绍了一个热键控制的类THotKeyConfig。该类可以从指定的xml配置文档中读入热键配置信息,并在程序指定的位置注册、注销、修改热键。

本文将不涉及XML文档的读写方法,也不会详述控件开发的方法。如果您对这些内容不了解,推荐您先略读一下相关的文章。关于xml文档的解析,可以到我的blog找到文章。

 

 

2 热键编程基础

2.1 API函数

在Delphi7中使用热键要用到如下几个函数:

 

//注册热键

BOOL RegisterHotKey(

    HWND hWnd, // 接受热键消息的窗口句柄

    int id, // 热键ID

    UINT fsModifiers, // 按键组合整数

    UINT vk    // 案件虚拟键码VK

   );

 

其中fsModifiers 值如下:

        1:  M_strDisplay:='Alt + ';

        2:  M_strDisplay:='Ctrl + ';

        3:  M_strDisplay:='Ctrl + Alt + ';

        4:  M_strDisplay:='Shift + ';

        5:  M_strDisplay:='Shift + Alt + ';

        6:  M_strDisplay:='Ctrl + Shift + ';

        7:  M_strDisplay:='Ctrl + Shift + Alt + ';

 

//注销热键

BOOL UnregisterHotKey(

 

HWND hWnd, //接受热键消息的窗口句柄

int id //热键ID

   );

注销时,根据注册时赋予的热键ID进行注销,因此在注册时必须保证ID唯一。

 

关于这两个WIN32 API函数的具体说明可以参考WIN32 SDK文档。

 

2.2 编程方法

基本的热键编程方法是定义2个窗体过程,和一个消息响应函数:

Procedure HotKeyOn;

Procedure HotKeyOff;

procedure HotKeyDown(var Msg: Tmessage); message WM_HOTKEY;

在HotKeyOn过程中调用API函数注册热键,代码可以是这样的:

procedure TfrmMain.HotKeyOn;

begin

    HKStep := 1;

    HKScreen := 2;

    HKComponent := 3;

    HKShowMain := 4;

    HKShowOI := 5;

    if not RegisterHotKey(Handle, HKStep, MOD_CONTROL, Ord('C')) then

        showmessage('can not register the hotkey "Ctrl-C"');

    if not RegisterHotKey(Handle, HKScreen, MOD_CONTROL, Ord('V')) then

        showmessage('can not register the hotkey "Ctrl-V"');

    if not RegisterHotKey(Handle, HKComponent, MOD_CONTROL, Ord('B')) then

        showmessage('can not register the hotkey "Ctrl-B"');

    if not RegisterHotKey(Handle, HKShowMain, MOD_CONTROL, VK_F11) then

        showmessage('can not register the hotkey "Ctrl-F11"');

    if not RegisterHotKey(Handle, HKShowOI, MOD_CONTROL, VK_F12) then

        showmessage('can not register the hotkey "Ctrl-F12"');

end;

 

在HotKeyOff过程中调用API函数注销热键,代码可以是这样的:

procedure TfrmMain.HotKeyOff;

begin

    UnRegisterHotKey(handle, HKStep);

    UnRegisterHotKey(handle, HKScreen);

    UnRegisterHotKey(handle, HKComponent);

    UnRegisterHotKey(handle, HKShowMain);

    UnRegisterHotKey(handle, HKShowOI);

end;

 

在HotKeyDown消息处理函数中判断系统消息,根据不同的热键组合执行响应的语句,代码可以是这样的:

procedure TfrmMain.HotKeyDown(var Msg: Tmessage);

begin

    if (Msg.LParamHi = Ord('C')) and (Msg.LParamLo = MOD_CONTROL) then

    ShowMessage('"Ctrl-C"')

    else if (Msg.LParamHi = Ord('V')) and (Msg.LParamLo = MOD_CONTROL) then

ShowMessage('"Ctrl-V"')

    else if (Msg.LParamHi = Ord('B')) and (Msg.LParamLo = MOD_CONTROL) then

ShowMessage('"Ctrl-B"')

    else if (Msg.LParamHi = VK_F11) and (Msg.LParamLo = MOD_CONTROL) then

    ShowMessage('"Ctrl-11"')

    else if (Msg.LParamHi = VK_F12) and (Msg.LParamLo = MOD_CONTROL) then

    ShowMessage('"Ctrl-12"')

end;

 

如果系统热键数量少、稳定不变,则适合使用这种方法。如果系统热键较多,而软件需求又要求热键可以由用户设置修改,则需要有一个自动化管理的模块来实现。因此我在学习了如上的方法后实现了一个热键自动管理的类。

 

 

3 实现概述

实现这个热键管理类我定义了1个记录体和3个类。可以将热键配置信息保存在一个独立的xml文档中,也作为子树加入到应用程序的配置文档中。

记录体ThotKeyStatus保存从XML配置树中读入的热键记录,该记录体的数组变量将被整个单元文件内的对象所共享。

类ThotKeyEdit是一个自定义的控件,用于接受用户输入的热键组合,一方面转化为系统可以接受的形式,另一方面也给用户一个即时反馈。

类TformHotkeyConfig是一个窗体类,该窗体类将根据从XML中读入的热键配置动态创建ThotKeyEdit控件,提供用户查看和修改热键。

类ThotKeyConfig是我们要使用和直接访问的类,它提供一个后台操作的功能,用户在引入该类后可以选择在程序指定位置读入XML配置文件、生效热键配置、打开TformHotKeyConfig提供的编辑窗体、保存配置到XML文件。另外该类在编程上为了控制对象的唯一性,采用了类方法MgetInstance来获得唯一对象,关于用类方法控制对象唯一性的方法可以参考我blog中的文章。

 

4 实现细节

4.1 XML配置文档结构

XML配置文档的结构可以如下:

<?xml version="1.0" encoding="UTF-8"?>

<configure>

    <hotkeys>

       <hotkey>

           <caption>添加SCREEN</caption>

           <hkid>101</hkid>

           <mod>2</mod>

           <vk>49</vk>

       </hotkey>

       <hotkey>

           <caption>新建STEP</caption>

           <hkid>102</hkid>

           <mod>2</mod>

           <vk>50</vk>

       </hotkey>

    </hotkeys>

</configure>

其中,<hotkeys>为保存热键配置的节点的子树树根。每个<hotkey>子树记录一个热键配置。

caption为热键名称,将显示在TformHotKeyConfig实例中的ThotKeyEdit对象的标题位置。

Hkid为热键唯一标识,对应上文API函数中的ID值,该值必须局部唯一。

Mod为热键模式,对应上文API函数中的fsModifier值。

Vk为热键虚拟键码,对应上文API函数中的VK值。

 

4.2 热键编辑控件 ThotKeyEdit

该控件的声明如下:

    //---------------------------------------

    //  热键编辑控件

    //---------------------------------------

    THotKeyEdit = class(TLabeledEdit)

    private

        //当前控件接收到的热键组合是否合法

        FKeySetValid:Boolean;

        //组合键

        FModValue:Integer;

        //虚拟键码

        FVirtualKeyValue:Integer;

        //修改合法后显示的颜色

        FValidateColor:TColor;

        //用来覆盖OnExit事件的函数

        procedure LostFocusEvent(Sender:TObject);

        //用来覆盖OnKeyDown事件的函数

        procedure GetHotKeyDownEvent(Sender: TObject; var Key: Word; Shift: TShiftState);

        //将热键数据转换为直观文字

        function  GetDisplayText:string;

        //热键组合合法执行的代码

        procedure ActionOnHotKeyValid;

        //热键组合非法执行的代码

        procedure ActionOnHotKeyInvalid;

    public

        //覆盖构造函数

        constructor Create(AOwner: TComponent); override;

        //外部请求将内部数据表现为直观文字

        procedure DisplayHotKey;

    published

        property HasValidKeySet:boolean read FKeySetValid;

        property VirtualKeyValue:integer read FVirtualKeyValue write FVirtualKeyValue;

        property KeyModValue:integer read FModValue write FModValue;

end;

 

ThotKeyEdit控件继承自TlabeledEdit控件,包含一个显示热键名称的LABEL和一个只读的EDIT区,在该区将显示用户输入的热键组合。控件的OnKeyDown事件被GetHotKeyDownEvent过程重写,在该过程中捕捉用户按下的按键组合,先将捕捉到的键位信息保存到私有字段中,然后调用GetDisplayText函数判断私有字段中的键位是否合法,并且返回由这些信息转换得到的热键字串。合法性将保存在一个私有布尔字段FKeySetValid中。

对于用户提供的热键布局,如果可以接受则控件edit区会变色,如果不能接受则会在失去焦点时清除内容,并恢复默认颜色。

 

 

4.3 热键自定义窗体类TformHotKeyconfig

该窗体类继承自Tform类,并需要UnitHotkeyConfigClass.dfm资源文件的支持。

类的声明代码如下:

    //---------------------------------------

    //  热键设定窗体

    //---------------------------------------

    TFormHotkeyConfig = class(TForm)

        GroupBoxLeft: TGroupBox;

        PanelRight: TPanel;

        ButtonYes: TButton;

        ButtonNo: TButton;

        procedure ButtonYesClick(Sender: TObject);

        procedure ButtonNoClick(Sender: TObject);

    private

        //用来保存动态创建的THotKeyEdit控件的对象列表

        FEditList:TObjectList;

    public

        constructor Create(AOwner: TComponent); override;

    end;

 

该类重写了构造方法,并在构造方法中根据从xml中读入的热键个数动态创建和初始化响应数量的ThotKeyEdit控件,因此需要一个私有成员FeditList来维护控件数组。

 

4.4 主类ThotKeyConfig

ThotKeyConfig的声明如下:

    //---------------------------------------

    //  主类:提供热键注册和编辑功能

    //---------------------------------------

    THotkeyConfig = class (TComponent)

    private

        //如果用户自定义配置文件路径则记录它

        FAssociatedXML : String;

        //配置窗体对象

        FConfigureForm : TFormHotkeyConfig;

        //热键响应窗体引用

        FWindow : TWinControl;

        //定位到保存热键记录的XML子树树根

        function XMLGetKeysetFather(AXML:TXMLDocument):IXMLNode;

        //隐藏的构造函数

        constructor Create(AOwner: TComponent);override;

    public

        //获得对象

        class function MGetInstance(AOwner:TWinControl):THotKeyConfig;

        //读入XML配置文件

        function LoadConfigFromXML(const AXMLFile:string='hotkey.xml'):boolean;

        //保存配置

        function SaveConfigToXML(const AXMLFile:string='hotkey.xml'):boolean;

        //注册所有热键设置

        function EnableAllHotkeys:Boolean;

        //注销热键

        procedure DisableAllHotkeys;

        //打开配置窗口

        procedure OpenConfigWindow;

    published

        property WindowHandlesHotkey : TWinControl write FWindow;

    end;

在该类中主要完成如下几个功能:

1.        读写解析XML配置文件

2.        注册注销系统热键

3.        提供热键修改窗体的入口

4.        通过类方法和类变量,管理类的对象在应用程序中的唯一性

 

4.4.1 解析XML文档

因为XML文档结构相对简单因此使用TXMLDocument类来实现,在LoadConfigFromXML方法中通过XMLGetKeysetFather函数定位到Hotkey节点,这样如果XML结构位置改变,只需要修改XMLGetKeysetFather函数就可以。读出的热键记录将保存到静态变量FkeyInfo和FkeyInfoCount中,他们是ThotKeyStatus的数组和计数器。

 

4.4.2 注册注销系统热键

两个对象方法负责自动完成热键的注册和注销:EnableAllHotkeys和DisableAllHotkeys。

热键注册时从FkeyInfo数组中读入键位信息并调用WIN32 API函数RegisterHotKey注册热键,如果注册成功则返回true。

在RegisterHotKey中需要一个窗体句柄来接受系统消息WM_HOTKEY,因此在调用EnableAllHotkeys之前需要为属性WindowHandlesHotkey赋一个窗体的引用值。或者在MgetInstance方法的参数中传递该窗体的引用。如果没有定义WindowHandlesHotkey会使热键无法注册。

 

4.4.3 热键编辑窗体

执行OpenConfigWindow方法将弹出模式窗体,提供用户编辑热键,该窗体就是TformHotKeyConfig的实例。

在窗体打开之前,为了不在编辑时触发热键消息,需要调用DisableAllHotkeys取消所有热键。

在窗体别关闭后检查静态变量isXMLNeedSave判断用户按下的是确认还是取消。如果是确认,则要保存热键配置到静态变量FkeyInfo和XML文档。最后根据FkeyInfo重新注册热键。

 

4.4.4 对象唯一性

因为一个应用程序中,对于ThotkeyConfig对象通常只需要一个就够了,如果在每个需要用到的地方都重新创建会影响程序执行效率。所以,我使用一个静态变量保存唯一对象的引用,然后公开一个方法MgetInstance让程序员得到ThotKeyConfig的实例对象。具体概念请访问我的blog。

因此类的编程模式如下:

    with THotKeyConfig.MGetInstance(Form1) do begin

        LoadConfigFromXML;

        EnableAllHotkeys ;

       //……

    end;

 

 

5 程序源代码

为了便于使用,我将3个类定义和1个记录体声明写在一个单独的UNIT中,这样会带来一些访问上的安全隐患,但是作为学习只用,程序员在调用时“自觉”一点就可以了 :-P

 

//--------------------------------------------------------------------------

//UNIT: UnitHotkeyConfigClass.pas

//SUMM: 热键控制类

//AUTH: CST

//DATE: 2005-8-15

//DESC: 本单元文件定义了一个保存热键项目的记录体、后台控制类、一个设定窗口类

//      以及一个需要用到的自定义控件THotKeyEdit。

//REFE: HotKeyConfig类使用到了自定义控件HotKeyEdit

//BUGS: No checking for duplicated hotkey sets

//      No checking for duplicated hotkey_id in xml

//       

//USES: 用户只需使用THotKeyConfig类,该类不能创建实例。

//      请使用THotKeyConfig.MGetInstance(Owner)方法来访问对象。

//--------------------------------------------------------------------------

unit UnitHotkeyConfigClass;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, ExtCtrls, Buttons, StrUtils, Contnrs, xmldom, XMLIntf,

  msxmldom, XMLDoc;

 

type

    //---------------------------------------

    //  热键组合

    //---------------------------------------

    THotKeyStatus = record

        FCaption:String[20];    //热键标题

        FHKID   :Integer;       //唯一ID

        FMod    :Integer;       //组合键

        FVK     :Integer;       //虚拟键码

    end;

 

 

 

    //---------------------------------------

    //  热键编辑控件

    //---------------------------------------

    THotKeyEdit = class(TLabeledEdit)

    private

        //当前控件接收到的热键组合是否合法

        FKeySetValid:Boolean;

        //组合键

        FModValue:Integer;

        //虚拟键码

        FVirtualKeyValue:Integer;

        //修改合法后显示的颜色

        FValidateColor:TColor;

        //用来覆盖OnExit事件的函数

        procedure LostFocusEvent(Sender:TObject);

        //用来覆盖OnKeyDown事件的函数

        procedure GetHotKeyDownEvent(Sender: TObject; var Key: Word; Shift: TShiftState);

        //将热键数据转换为直观文字

        function  GetDisplayText:string;

        //热键组合合法执行的代码

        procedure ActionOnHotKeyValid;

        //热键组合非法执行的代码

        procedure ActionOnHotKeyInvalid;

    public

        //覆盖构造函数

        constructor Create(AOwner: TComponent); override;

        //外部请求将内部数据表现为直观文字

        procedure DisplayHotKey;

    published

        property HasValidKeySet:boolean read FKeySetValid;

        property VirtualKeyValue:integer read FVirtualKeyValue write FVirtualKeyValue;

        property KeyModValue:integer read FModValue write FModValue;

    end;

 

 

 

    //---------------------------------------

    //  热键设定窗体

    //---------------------------------------

    TFormHotkeyConfig = class(TForm)

        GroupBoxLeft: TGroupBox;

        PanelRight: TPanel;

        ButtonYes: TButton;

        ButtonNo: TButton;

        procedure ButtonYesClick(Sender: TObject);

        procedure ButtonNoClick(Sender: TObject);

    private

        //用来保存动态创建的THotKeyEdit控件的对象列表

        FEditList:TObjectList;

    public

        constructor Create(AOwner: TComponent); override;

    end;

 

 

   

 

    //---------------------------------------

    //  主类:提供热键注册和编辑功能

    //---------------------------------------

    THotkeyConfig = class (TComponent)

    private

        //如果用户自定义配置文件路径则记录它

        FAssociatedXML : String;

        //配置窗体对象

        FConfigureForm : TFormHotkeyConfig;

        //热键响应窗体引用

        FWindow : TWinControl;

        //定位到保存热键记录的XML子树树根

        function XMLGetKeysetFather(AXML:TXMLDocument):IXMLNode;

        //隐藏的构造函数

        constructor Create(AOwner: TComponent);override;

    public

        //获得对象

        class function MGetInstance(AOwner:TWinControl):THotKeyConfig;

        //读入XML配置文件

        function LoadConfigFromXML(const AXMLFile:string='hotkey.xml'):boolean;

        //保存配置

        function SaveConfigToXML(const AXMLFile:string='hotkey.xml'):boolean;

        //注册所有热键设置

        function EnableAllHotkeys:Boolean;

        //注销热键

        procedure DisableAllHotkeys;

        //打开配置窗口

        procedure OpenConfigWindow;

    published

        property WindowHandlesHotkey : TWinControl write FWindow;

    end;

 

 

procedure Register;

 

implementation

 

{$R *.dfm}

 

//-----------------------------------------------------------------------

//  单元内全局变量

//-----------------------------------------------------------------------

var

    //共享从XML中读入的热键配置信息

    FKeyInfo : array of THotKeyStatus;

    //读入的热键记录个数

    FKeyInfoCount: Integer;

    //是否需要保存到XML中

    isXMLNeedSave:Boolean;

    //实体

    HK_Instance:THotkeyConfig;

 

 

//-----------------------------------------------------------------------

//  自定义控件可以被注册

//-----------------------------------------------------------------------

procedure Register;

begin

  RegisterComponents('CST', [THotKeyEdit]);

end;

 

 

 

{********************************************************

*********************************************************

*******************  THotkeyConfig  *********************

*********************************************************

********************************************************}

 

//-----------------------------------------------------------------------

//  构造函数

//-----------------------------------------------------------------------

constructor THotKeyConfig.Create (AOwner: TComponent);

begin

    inherited;

end;

 

 

//-----------------------------------------------------------------------

//NAME: MGetInstance

//SUMM: 获得类的唯一实例

//PARA: AOwner

//RETN: 唯一实例

//AUTH: CST

//DATE: 2005-8-18

//DESC: 类方法实现对象唯一性控制

//-----------------------------------------------------------------------

class function THotKeyConfig.MGetInstance(AOwner:TWinControl):THotKeyConfig;

begin

    if HK_Instance = nil then begin

        HK_Instance:=Create(AOwner);

        HK_Instance.WindowHandlesHotkey := AOwner;

    end;

    Result:=HK_Instance;

end;

 

 

//-----------------------------------------------------------------------

//NAME: EnableAllHotkeys

//SUMM: 注册所有热键

//PARA: N/A

//RETN: TRUE-成功

//AUTH: CST

//DATE: 2005-8-15

//DESC: 在应用程序加载时由用户显式调用。热键配置修改后被类自动调用重新注册

//      先判断热键Listener窗体是否赋值,然后调用WIN32 API注册

//-----------------------------------------------------------------------

function THotkeyConfig.EnableAllHotkeys:Boolean;

var

    M_Index:integer;

    M_ErrText:string;

begin

    Result:=True;

 

    //CHECK HOTKEY HANDLE WINDOW DEFINED

    if FWindow=nil then begin

        ShowMessage('热键处理窗体未定义。'+#13+'请使用WindowHandlesHotkey方法。');

        result:=false;

        exit;

    end;

 

    //REGISTER BY LOOP

    for M_Index := 0 to FKeyInfoCount - 1 do begin

        //SKIP UNDEFINED HOTKEY EVENTS

        if FKeyInfo[M_Index].FMod < 1 then continue;

        if FKeyInfo[M_Index].FVK  < 1 then continue;

        //START TO REGISTER HOTKEY

        if not RegisterHotKey( FWindow.Handle,

                               FKeyInfo[M_Index].FHKID,

                               FKeyInfo[M_Index].FMod ,

                               FKeyInfo[M_Index].FVK  ) then begin

            //REGISTER FAILURE PROCEDURE                              

            Result:=False;

            M_ErrText:=Format('无法注册名为%s的热键。',[FKeyInfo[M_Index].FCaption]);

            //ShowMessage(M_ErrText);

        end;    //end of if

    end;    //end of for

end;

 

//-----------------------------------------------------------------------

//NAME: DisableAllHotkeys

//SUMM: 注销所有热键

//PARA: N/A

//RETN: TRUE-成功

//AUTH: CST

//DATE: 2005-8-15

//DESC: 在进入热键编辑之前要调用此方法注销热键。

//-----------------------------------------------------------------------

procedure THotkeyConfig.DisableAllHotkeys;

var

    M_Index:integer;

begin

    for M_Index := 0 to FKeyInfoCount - 1 do

        UnRegisterHotKey( FWindow.Handle, FKeyInfo[M_Index].FHKID);

end;

 

 

//-----------------------------------------------------------------------

//NAME: XMLGetKeysetFather

//SUMM: 定位到保存热键记录的XML子树树根

//PARA: AXML-XML文档

//RETN: 树根节点

//AUTH: CST

//DATE: 2005-8-18

//DESC: 定位到保存热键记录的XML子树树根。

//      如果要改变XML结构,则只要修改这里的定位语句。

//-----------------------------------------------------------------------

function THotkeyConfig.XMLGetKeysetFather(AXML:TXMLDocument):IXMLNode;

var

    M_SearchNode:IXMLNode;

begin

    //NAVIGATE THROUGH XML CONFIGURE FILE

    M_SearchNode:=AXML.Node;

    M_SearchNode:=M_SearchNode.ChildNodes.Nodes['configure'];

    M_SearchNode:=M_SearchNode.ChildNodes.Nodes['hotkeys'];

    Result:= M_SearchNode;

end;

 

 

 

//-----------------------------------------------------------------------

//NAME: LoadConfigFromXML

//SUMM: 从XML文档中读取热键设置,并注册生效

//PARA: AXMLFile-XML文档路径,默认为EXE同根的hotkey.xml

//RETN: TRUE-成功

//AUTH: CST

//DATE: 2005-8-15

//DESC: 使用TXMLDocuement对象解析配置文档,将读取的记录保存到类变量中

//      FKeyInfo数组记录读入的热键组合,FKeyInfoCount记录动态数组大小

//-----------------------------------------------------------------------

function THotkeyConfig.LoadConfigFromXML(const AXMLFile:string='hotkey.xml'):boolean;

var

    M_ConfigXML:TXMLDocument;

    M_SearchNode, M_PropNode:IXMLNODE;

    M_Index :integer;

begin

    result:=False;

 

    //Q:为何构造方法参数为nil就会无法解析节点?

    M_ConfigXML:=TXMLDocument.Create(Self);

    try

        //OPEN XML CONFIGURE FILE

        with M_ConfigXML do begin

            LoadFromFile(AXMLFile);

            Options := [];

            Active := True;

        end;

 

        //RECORD ASSOCIATED XML CONFIGURATION FILE

        FAssociatedXML := AXMLFile;

 

        //GET THE ROOT WE WANT

        M_SearchNode:=XMLGetKeysetFather(M_ConfigXML);

 

        //GET COUNT FOR HOTKEY SETS

        FKeyInfoCount:=M_SearchNode.ChildNodes.Count ;

        SetLength(FKeyInfo, FKeyInfoCount);

 

        //LOOP TO READ EVERY KEYSET

        for M_Index := 0 to FKeyInfoCount - 1 do begin

            M_PropNode:=M_SearchNode.ChildNodes.Nodes[M_Index];

            with FKeyInfo[M_Index] do begin

                FCaption := M_PropNode.ChildValues['caption'];

                FHKID  := M_PropNode.ChildValues['hkid'];

                FMod  := M_PropNode.ChildValues['mod'];

                FVK  := M_PropNode.ChildValues['vk'];

            end;  //end of with

        end;  //end of for

    finally

        M_ConfigXML.Active := False;

        FreeAndNil(M_ConfigXML);

    end;

end;

 

 

//-----------------------------------------------------------------------

//NAME: SaveConfigToXML

//SUMM: 保存修改的热键配置到XML文档

//PARA: AXMLFile-XML文档路径

//RETN: TRUE-成功

//AUTH: CST

//DATE: 2005-8-15

//DESC: 配置窗口确认关闭后调用

//-----------------------------------------------------------------------

function THotkeyConfig.SaveConfigToXML(const AXMLFile:string='hotkey.xml'):boolean;

var

    M_ConfigXML:TXMLDocument;

    M_SearchNode, M_PropNode:IXMLNODE;

    M_Index :integer;

begin

    result:=False;

 

    M_ConfigXML:=TXMLDocument.Create(Self );

    try

        //OPEN XML CONFIGURE FILE

        with M_ConfigXML do begin

            LoadFromFile(AXMLFile);

            Options := [];

            Active := True;

        end;

 

        //GET THE ROOT WE WANT

        M_SearchNode:=XMLGetKeysetFather(M_ConfigXML);

 

        //LOOP TO READ EVERY KEYSET

        for M_Index := 0 to FKeyInfoCount - 1 do begin

            M_PropNode:=M_SearchNode.ChildNodes.Nodes[M_Index];

            with FKeyInfo[M_Index] do begin

                M_PropNode.ChildValues['caption']:=FCaption;

                M_PropNode.ChildValues['hkid']:=FHKID;

                M_PropNode.ChildValues['mod']:=FMod;

                M_PropNode.ChildValues['vk']:=FVK;

            end;  //end of with

        end;  //end of for

 

        //SAVE CHANGES

        M_ConfigXML.SaveToFile(AXMLFile);

    finally

        M_ConfigXML.Active := False;

        FreeAndNil(M_ConfigXML);

    end;

 

end;

 

 

 

//-----------------------------------------------------------------------

//NAME: OpenConfigWindow

//SUMM: 打开配置窗口

//PARA: N/A

//RETN: N/A

//AUTH: CST

//DATE: 2005-8-15

//DESC: 窗体对象为 FConfigureForm 成员

//-----------------------------------------------------------------------

procedure THotKeyConfig.OpenConfigWindow ;

var

    M_ErrMsg:String;

begin

    if FConfigureForm = nil then FConfigureForm:=TFormHotkeyConfig.Create(nil);

    try

        //默认是不要保存修改

        isXMLNeedSave:=False;

 

        //设置之前先注销所有热键

        DisableAllHotkeys ;

 

        //打开设置窗口

        FConfigureForm.ShowModal;

 

        if isXMLNeedSave then begin

            //修改后按下『确认』生效并保存

            if EnableAllHotkeys then

                begin

                    //新设置热键注册成功

                    MessageBox(Application.Handle, '所有热键都成功注册。'+#13+'点击确认保存所有热键设置。', '提示', MB_OK + MB_ICONINFORMATION);

                    SaveConfigToXML(FAssociatedXML);

                end     //end of if

            else

                begin

                    //新设置热键有冲突

                    M_ErrMsg:='您设置的热键组合中有一项或多项没有注册成功。' + #13 +

                              '也许是和其他应用程序产生了冲突,您可以尝试更换其他按键组合。' + #13 +

                              '请问是否仍然要保存这次的设置,如果保存请按“是”,我们将在下次软件启动的时候'+

                              '再次尝试注册您的热键配置,您可以在这之前注销或修改其他应用程序的冲突设置。';

                    if MessageBox(Application.Handle, PChar(M_ErrMsg), '提示',MB_YESNO+MB_ICONQUESTION)=IDYES then SaveConfigToXML(FAssociatedXML);

                end;

        end

        else begin

            //按下『取消』按钮,但是还是要恢复原先的热键

            EnableAllHotkeys;

        end;

       

    finally

        FreeAndNil(FConfigureForm);

    end;

end;

 

 

{********************************************************

*********************************************************

****************  TFormHotkeyConfig  ********************

*********************************************************

********************************************************}

 

//-----------------------------------------------------------------------

//NAME: Create

//SUMM: TFormHotkeyConfig的构造函数

//AUTH: CST

//DATE: 2005-8-15

//DESC: 继承TForm的构造函数,动态创建THotKeyEdit控件。

//      将窗体上的热键接受控件的OnKeyDown事件改写。

//-----------------------------------------------------------------------

constructor TFormHotkeyConfig.Create(AOwner: TComponent);

var

    M_Index, M_Top:integer;

    HKEdit:THotkeyEdit;

const

    MLEFT = 10;

    MWIDTH = 200;

    MHEIGHT = 21;

    MMARGIN = 30;

begin

    inherited;

 

    //HOTKEYEDITORS

    FEditList := TObjectList.Create ;

    M_Top := 0;

    for M_Index := 0 to FKeyInfoCount - 1 do begin

        //计算控件位置,纵向排列

        M_Top:= MMARGIN + M_Index * (MHEIGHT+MMARGIN);

        //根据读入的XML节点动态创建热键编辑控件

        HKEdit:=THotKeyEdit.Create(Self);

        with HKEdit do begin

            //定义样式

            Parent:=Self.GroupBoxLeft;

            SetBounds(MLEFT,M_Top,MWIDTH,MHEIGHT);

            LabelPosition := lpAbove ;

            EditLabel.Caption := FKeyInfo[M_Index].FCaption;

            EditLabel.Width := MWIDTH;

            //定义初始数据

            VirtualKeyValue := FKeyInfo[M_Index].FVK;

            KeyModValue := FKeyInfo[M_Index].FMod;

            //按照定义的数据显示热键组合

            DisplayHotKey;

        end;    //end of with

        //保存组件到对象列表

        FEditList.Add(HKEdit);

    end;    //end of for

 

    Height:= M_Top + MHEIGHT + MMARGIN;

end;

 

 

//------------------------------------------------------------

//  确定

//------------------------------------------------------------

procedure TFormHotkeyConfig.ButtonYesClick(Sender: TObject);

var

    M_Index:integer;

begin

    //CONVERT HK_EDITOR DATA TO HOTKEY INFO ARRAY

    for M_Index := 0 to FKeyInfoCount - 1 do begin

        FKeyInfo[M_Index].FMod := (FEditList.Items[M_Index] as THotKeyEdit).KeyModValue ;

        FKeyInfo[M_Index].FVK := (FEditList.Items[M_Index] as THotKeyEdit).VirtualKeyValue;

    end;

    //END OF CONVERT

   

    Close;

    isXMLNeedSave:=True;

end;

 

 

//------------------------------------------------------------

//  取消

//------------------------------------------------------------

procedure TFormHotkeyConfig.ButtonNoClick(Sender: TObject);

begin

    if MessageBox(Self.Handle,'是否要放弃修改并关闭窗口?','提示',MB_YESNO+mb_iconinformation) = IDYES then

    begin

        Close;

        isXMLNeedSave:=False;

    end;

end;

 

 

 

 

{********************************************************

*********************************************************

*********************  THotKeyEdit  *********************

*********************************************************

********************************************************}

 

 

 

//-----------------------------------------------------------------------

//  HotKeyEdit控件构造函数

//-----------------------------------------------------------------------

constructor THotKeyEdit.Create(AOwner: TComponent);

begin

    inherited;

    ReadOnly := True;

    OnKeyDown := GetHotKeyDownEvent;

    OnExit := LostFocusEvent;

    FValidateColor := clSkyBlue;

end;

 

 

//-----------------------------------------------------------------------

//NAME: GetDisplayText

//SUMM: 将热键信息转换为显示字串

//PARA: N/A

//RETN: 热键转换的显示结果

//AUTH: CST

//DATE: 2005-8-15

//DESC: 型如:"Ctrl + Alt + Shift + A "为正确

//      数据来源 FVirtualKeyValue, FModValue

//      判断组合是否合法,记录在FKeySetValid中

//-----------------------------------------------------------------------

function THotKeyEdit.GetDisplayText:string;

var

    M_strDisplay:String;

const

    SPLUS = ' + ';

begin

    FKeySetValid := True;

 

    //处理按键组合

    case FModValue of

        1:  M_strDisplay:='Alt + ';

        2:  M_strDisplay:='Ctrl + ';

        3:  M_strDisplay:='Ctrl + Alt + ';

        4:  M_strDisplay:='Shift + ';

        5:  M_strDisplay:='Shift + Alt + ';

        6:  M_strDisplay:='Ctrl + Shift + ';

        7:  M_strDisplay:='Ctrl + Shift + Alt + ';

    else

        begin

            M_strDisplay := '';

            FKeySetValid := False;

        end;

    end;

 

    //处理键码

    case FVirtualKeyValue of

    VK_F1..VK_F12:

        M_strDisplay := M_strDisplay + 'F'+IntToStr(FVirtualKeyValue - VK_F1 + 1);

    Ord('A')..Ord('Z'), Ord('0')..Ord('9'):

        M_strDisplay := M_strDisplay + Chr(FVirtualKeyValue);

    else

        begin

            M_strDisplay := M_strDisplay ;

            FKeySetValid := False;

        end;

    end;

 

    result:=M_strDisplay;

end;

 

 

 

//-----------------------------------------------------------------------

//NAME: LostFocusEvent

//SUMM: 控件失去焦点时检查热键合法性

//PARA: Sender-控件

//RETN: N/A

//AUTH: CST

//DATE: 2005-8-15

//DESC: 此函数将用来覆盖4个TLabelEdit的OnExit事件

//-----------------------------------------------------------------------

procedure THotKeyEdit.LostFocusEvent(Sender:TObject);

begin

    if not FKeySetValid then begin

        Text:='';

        FModValue := 0;

        FVirtualKeyValue := 0;

    end;

end;

 

 

 

//-----------------------------------------------------------------------

//NAME: GetHotKeyDownEvent

//SUMM: 接受用户输入的热键并判断是否合法的时间函数

//PARA: Sender-控件  Key-虚拟键码 Shift-辅助键信息

//RETN: N/A

//AUTH: CST

//DATE: 2005-8-15

//DESC: 此函数将用来覆盖OnKeyDown事件

//

//-----------------------------------------------------------------------

procedure THotKeyEdit.GetHotKeyDownEvent(Sender: TObject; var Key: Word; Shift: TShiftState);

var

    M_StrDisplay:String;

begin

    //READ HOTKEY SET MODE

    FModValue := 0;

    if (ssCtrl in Shift)  then FModValue := FModValue + 2;

    if (ssAlt  in Shift)  then FModValue := FModValue + 1;

    if (ssShift in Shift) then FModValue := FModValue + 4;

 

    //READ HOTKEY SET VIRTUAL KEY

    FVirtualKeyValue  := Key;

 

    //GET DISPLAY TEXT AND JUDGE WHETHER KEYSET IS VALIDATE

    M_StrDisplay := GetDisplayText;

 

    //REFLECTION

    if FKeySetValid then

        ActionOnHotKeyValid

    else

        ActionOnHotKeyInvalid ;

    Text := M_StrDisplay;

end;

 

//---------------------------------------

//  在动态创建时显示组合键

//---------------------------------------

procedure THotKeyEdit.DisplayHotKey;

begin

    Text := GetDisplayText ;

end;

 

 

//---------------------------------------

//  热键组合合法执行的代码

//---------------------------------------

procedure THotKeyEdit.ActionOnHotKeyValid;

begin

    Color:=FValidateColor;

end;

 

//---------------------------------------

//  热键组合非法执行的代码

//---------------------------------------

procedure THotKeyEdit.ActionOnHotKeyInvalid;

begin

    Color := clWhite;

end;

 

 

 

end.

 

6 小结

6.1 没有解决的一些问题

TXMLDocument的对象在创建时如果Owner参数为nil则无法解析到节点,如果使用带文档路径参数的重载的构造函数也会如此,因为在TXMLDocument的源码中重载的版本Owner也是nil。为了规避这个问题,我牺牲了效率而将Owner置为Application并手动释放了文档对象。考虑到如果使用self可能会因为释放两次而产生错误,而Application的释放影响不会很大。

 

没有实现对于XML文档合法性的检验,仅过滤了超出范围的MOD和VK值,对于HKID是否唯一没有做检查。

 

没有实现对于用户定义的热键之间的冲突,在TformHotKeyConfig中没有判断是否设置的了相同的热键。

 

热键编辑控件可以注册到Pallete中,ThotKeyConfig类尚未控件化,如果控件化可能需要改变对象调用方式,公开构造函数允许创建多个实例。取消MgetInstance方法。

 

6.2 程序心得

虽然Delphi中对于热键的使用也不繁琐,但是使用本方法可以利用流行的xml记录热键是挺诱人的,只要稍加修改就可以继承到应用程序中。而且这样自由度比较高,热键数量、名称、布局都是可以自定义的。

 

在组件化上,我只封装了ThotKeyEdit控件,而没有将ThotKeyConfig类严格封装。因此只能通过代码手动创建和调用。热键编辑窗口是一个挺方便的设计,可以让使用该类的用户不必关心热键编辑的实现。

 

在不断的OO开发中,我也在摸索,程序中难免会有一些不如意之处,我诚心希望各位给我提出意见,我也很高兴能在相关的问题上和大家一起讨论讨论。

 

本程序的相关代码和测试示例可以在我的YAHOO公文包上下载。

 

VB.NET注册热键示例 Public Class Form1    Inherits System.Windows.Forms.Form#Region " Windows 窗体设计器生成的代码 "    Public Sub New()        MyBase.New()        该调用是 Windows 窗体设计器所必需的。        InitializeComponent()      阅读详情

相关推荐

快速启动程序的热键编码实战

本文还有配套的精品资源,点击获取 简介:热键启动程序技术通过键盘快捷键提高用户工作效率,尤其适用于经常使用的软件。在Windows平台上,C#语言利用user32.dll库中的RegisterHotKey和UnregisterHotKey函数来实现热键的注册与注销。此外,还展示了如何通过接收WM_HOTKEY消息来执行程序启动的逻辑。对于Linux或macOS平台,使用不同...

weixin_42576804的博客 1355

Delphi 全局热键注册+使用

RAD Studio 10.2.3 测试√ 全局变量: var mHotKey01, mHotKey02: Integer; 1、在程序创建的时候或者窗体显示的时候注册热键 begin // 原子【mHotKey01】 mHotKey01 := GlobalAddAtom('xiaoyin_HotKey_CTRL_F1') - $C000; //注册热键【Ctrl + F1】 RegisterHotKey(Handle, mHotKey01, MOD_CONTROL, VK_F1)

小印丶的笔记 1998

Delphi 注册和删除热键举例.rar

Delphi 注册HotKEY热键功能,程序功能包括注册热键、删除热键,比较初级的Delphi自定义热键的例子,仅供Delphi初学者参考,编译请在Delphi7环境下进行。下面来分享两者的具体实现代码:   以下是注册热键的功能,通过修改注册表实现:   procedure TForm1.FormCreate(Sender: TObject);   begin    hotkeyid:=GlobalAddAtom(pchar('UserDefineHotKey'))-$C000;    registerhotkey(handle,hotkeyid,MOD_CONTROL or mod_Alt,$41);   end;   以下是删除热键的功能,同样通过修改注册表实现:   procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);   begin    unregisterhotkey(handle,hotkeyid);    DeleteAtom(HotKeyID);   end;

DELPHI如何注册系统热键

用DELPHI如何注册系统热键 (2003年10月21日) 发表日期:2003-3-1 文章作者:未知  已浏览: 357 次 var i=9; fun

dingrj的专栏 2361

DELPHI 7 控制热键

通过钩子控制某一热键是否可用 WM_KEYDOWN,WM_SYSKEYDOWN,WM_KEYUP,WM_SYSKEYUP: if (p.vkCode = VK_LWIN) OR (p.vkCode = VK_RWIN)//判断按下的是不是某一键值

全局热键隐藏当前窗口(附delphi源码)

你是公司白领吗?是不是总是偷偷在电脑上玩连连看之类的小游戏?老板过来了,怎么办?不用担心,有我在,只要按下ALT+Z就可以隐藏当前窗口,再按即会显示出来刚刚被隐藏的窗口.双击有说明 :)<br>我的博客http://www.kumouse.com

Delphi7 全局快捷键

注册全局快捷键 // Ctrl+F5 // 设置一个唯一ID HotKeyID := GlobalAddAtom('HotKeyID'); // 辅助快捷键 MOD_ALT, MOD_CONTROL, MOD_SHIFT, MOD_WIN, 0 ControlKeyInt := MOD_CONTROL; FnKeyInt := VK_F5; RegisterHotKey(self.Handle, HotKeyID, ControlKeyInt, FnKeyInt); 监听全局快捷键事件 // 定义函数原型

记昨日书的博客 611

delphi设置全局快捷键

delphi设置全局快捷键

D7全局热键

一个简单的Delphi7全局热键 unit uHotKey; interface uses Windows, SysUtils, Messages, Classes; const VK_0=$30; //0键 VK_1=$31; //1键 VK_2=$32; //2键 VK_3=$33; //3键 VK_4=$34; //4键 VK_5=$35; ...

336

Delphi注册系统热键..rar

Delphi注册系统热键..rar

【EMC电磁兼容】02.04——原理图的实战落地细节

原理图上的关于EMC的落地体现一、元器件的选型二、原理图上的EMC体现在哪里?1.芯片电源管脚滤波去耦:2.时钟电路滤波设计3.低速电路滤波抗干扰设计4.通讯接口电路的防护滤波5.系统输入电源端口电路的防护滤波6.系统接地的定义7.芯片软件功能的审查 一、元器件的选型 ​ 原理图最初设计涉及到选型元器件方面: 元器件选型 不仅仅功能需要满足要求,还需要考虑其它细节参数在不同应力下的反应,封装的不同也会产生不同的变化。 元器件替代 常常因为成本原因进行器件替代,除了要考虑功能参数相同时也要考虑系统参数

Time to Forget 2243

delphi 多热键注册

unit Unit1;       interface      uses     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,      Dialogs;       type     TForm1 = class(TForm)        pro

123123121 956

OpenClaw Browser Relay Extension 鉴权失败与 invalid handshake 问题的终极解决方案

在使用 OpenClaw 浏览器插件 (Browser Relay Extension) 时,许多用户可能会遇到两个主要问题:一是配置端口错误导致的连接失败,二是鉴权失败 (Gateway token rejected)。本文将详细解析这两个问题并提供解决方案。

gerryke的blog 5559

易语言:请问如何注册热键框,不是简单的注册热键

如何注册热键框??、不是简单的注册热键 .版本 2 .支持库 shellEx .支持库 spec .子程序 _标签1_反馈事件, 整数型 .参数 参数一, 整数型 .参数 参数二, 整数型 .判断开始 (h [1] = 参数一)     执行子程序 (z [1], ) .判断 (h [2] = 参数一)     执行子程序 (z [2], ) .判断 (h [3] =

2776

zedboard(5)spi轮询和中断

一个SPI可以有几个从设备 在程序中使用 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel) 选择。其实就是吧对应设备的ss拉低。 备注:只选一个ss,可以不用指定。(感觉,还没测试) 这是xspips.c中定义的函数,发送和接收有 XSpiPs_Transfer 和 XSpiPs_PolledTransfer 两个函数,分别采用中断和轮询模式。    一、轮询模式 米联客参考代码,SpiPs_Init中部分和官方例程流程一样,Spi

Kiss丶小坏 5889

【RT-DETR涨点改进】全网独家-特征融合改进篇 | AAAI 2025 顶会| 高效涨点,RT-DETR利用CDFA对比度特征聚合模块,适用于目标检查(全网独家创新)

本文提出了一种基于CDFA模块的多级特征融合优化RT-DETR模型,用于解决医学图像分割中的软边界模糊、小目标和共现现象等问题。CDFA模块通过对比度特征聚合、局部特征增强和多级注意力机制,有效提升模型性能。研究提供了三种改进方案(rtdetr-r18/y50/l-CDFA),并在多个医学数据集上验证了其有效性。核心创新包括语义信息解耦、对比驱动特征融合和尺寸感知解码器。实验结果表明,该方法在分割精度和鲁棒性方面达到SOTA水平。

Ai缝合怪、助力小伙伴高效发论文 509

Qt5注册全局热键

简述最近写Qt程序需要用到注册全局热键,百度了好多,也没有找到成功的(可能我用的是假百度吧),几天后,找到一个案例,终于成功。本文全部是基于这个例程进行编写的。正所谓,站在巨人的肩上! 尽量写的详细一点,使新手学习过程中少走弯路。文章最后会有项目全部代码,仅供参考。相关环境 Qt 5.6 Windows 10 没有在linux系统运行,我只针对windows做了测试。实例新建一个窗口程

郝凡的博客 7924

【RT-DETR涨点改进】独家小目标涨点改进篇 | TGRS 2025 | RT-DETR引入ABRNet小目标检测顶刊中的:ARF自适应性感受野和MCA双向交叉轴注意力,适合小目标检测有效涨点

本文提出了一种改进的RT-DETR小目标检测方法,通过集成自适应感受野模块(ARF)和多尺度交叉轴注意力模块(BC)来提升检测性能。ARF模块采用多种卷积核动态调整感受野,有效捕获多尺度目标特征并减少背景干扰;BC模块通过多尺度交叉轴注意力机制增强全局信息提取和特征融合能力。实验表明,该方法在复杂背景下显著提升了红外小目标检测的精度和效率,同时降低了计算开销。文章详细介绍了模块结构、原理及实现代码,并提供了多种改进配置方案,为小目标检测任务提供了有效的解决方案。

Ai缝合怪、助力小伙伴高效发论文 570

第九节 组合热键与注册全局热键

第九节 组合热键与注册全局热键 要完成的功能是按下系统热键+其他的键可以响应 一.用虚函数添加组合热键 1->在主对话框类添加PreTranslateMessage虚函数来捕获键盘信息 2->设置按键状态宏 #define IsKeyPressed(nVirtKey)  ((GetKeyState(nVirtKey) & (1 #define IsKeyToggle

转基因蚊子的博客 643

DB文件在编程中的作用及示例代码

通过使用DB文件,我们可以实现数据的持久化存储,并能够高效地进行数据的增删改查操作。在本文中,我们以SQLite数据库为例,演示了如何使用Python语言创建和操作DB文件的示例代码。在实际的编程中,我们可以根据具体的需求和使用的数据库系统来进行更复杂的操作和优化。通过使用DB文件,我们可以实现数据的持久化存储,确保数据在程序关闭后也能被保留,并且能够高效地进行数据检索和更新。在本文中,我们将探讨DB文件的作用,并提供一些示例代码展示如何在编程中使用DB文件。上述代码中,我们使用SQLite提供的。

CodeSpark的博客 1821

【异常】OpenClaw提示Message ordering conflict - please try again. If this persists, use /new to start a fr

摘要:OpenClaw助手出现"Message ordering conflict"异常时,表明会话消息排序冲突,主要由消息队列时序错乱、会话同步异常或上下文过载引起。解决方案包括:1)基础重试暂停后单发指令;2)最优方案是发送/new重置会话;3)极端情况下需重启客户端或检查指令格式。预防建议包括避免高频并发指令、定期重置会话及确保网络稳定。该报错属业务层异常,不影响账号安全。

奶爸的编程之路,也就一周冷个三天 424

利用热键控制鼠标移动的一个程序

本程序可以使用热键来将鼠标移动到某一个指定的坐标。是一个定义热键的示例程序。本程序的热键为小键盘的5,在编辑框内可以指定坐标。 unit MainUnit;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  StdCtrls, Mask;type 

blog 1975

Allegro23.1新功能之软件自带阻抗计算工具操作指导

Allegro升级到了23.1后,软件新增了一个自带阻抗计算的功能,如下图。Propagation velocity:传输速度,单位是光速的多少倍。Dielectric constant输入介电常数,这里使用常规4。新功能之软件自带阻抗计算工具。如何使用,具体操作如下。

weixin_54787054的博客 783

Qt5注册全局热键实现对话框显示与隐藏

Qt5注册全局热键简述最近写Qt程序需要用到注册全局热键,百度了好多,也没有找到成功的(可能我用的是假百度吧),几天后,找到一个案例,终于成功。本文全部是基于这个例程进行编写的。正所谓,站在巨人的肩上! 尽量写的详细一点,使新手学习过程中少走弯路。文章最后会有项目全部代码,仅供参考。相关环境Qt 5.6 Windows 8.1没有在linux系统运行,我只针对windows做了测试。实例新建一个窗...

komtao520的博客 1812

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

GlobalHotKey:实现全局热键注册与事件处理

GlobalHotKey:实现全局热键注册与事件处理 项目介绍 GlobalHotKey 是一个轻量级、跨平台的开源库,它提供了一种简单的方式在 WPF 和 WebForms 应用程序中设置系统级全局热键,并响应其事件。GlobalHotKey 通过提供简单的 API 接口,使得开发者能够轻松注册全局热键,无需深入了解复杂的 Windows API。 项目技术分析 GlobalHotKey 基于....

gitblog_01002的博客 1084

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

上一篇: 使用类方法控制实例的唯一性
下一篇: 多线程图片转换类实现STEP BY STEP
mrtechno
博客等级 码龄21年 9粉丝 12原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值