锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源英语 / 键盘(热键)定制类
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

键盘(热键)定制类

Introduction

An essential feature of any "professional" program is a keyboard customization dialog, where users can assign hotkeys of their choice for all menu commands. It looks like a big job, at least it did to me when I was contemplating adding it to my xplorer². Do I need to have script-ready structure for all the commands? Do I have to add text and description for each one of them? What about translations of the GUI?任何“专业”程序的基本功能是键盘自定义对话框,用户可以在其中为所有菜单命令分配所选的热键。它看起来像一个大工作,至少它在我考虑将它添加到我的xplorer²时对我做了。我是否需要为所有命令提供脚本就绪结构?我是否必须为每一个添加文字和说明?GUI的转换怎么样?

Searching in MSDN, CodeProject, and usenet groups for a readymade solution - even paid - turned out fruitless. Searching SourceForge with Krugle (great resource) dug up some promising code snippets, but no complete solution.在MSDN,CodeProject和usenet小组中搜索现成的解决方案 - 甚至付费 - 结果毫无结果。使用Krugle(很好的资源)搜索SourceForge 挖出一些有希望的代码片段,但没有完整的解决方案。

As you do, I ended up writing my own keyboard customization class from scratch. The good news is that it makes adding hotkey customization to your WTL application a breeze: just add a header file, a dialog resource, a few lines to the frame creation, and you are done. All the command strings are read from your existing menu structure.正如您所做的那样,我最终从头开始编写自己的键盘自定义类。好消息是,它可以轻松地为您的WTL应用程序添加热键自定义:只需添加一个头文件,一个对话框资源,几行添加到框架的代码,您就完成了。从现有菜单结构中读取所有命令字符串。

Usability wise, the dialog resembles the hotkey customization dialog of VS6, albeit without command categories. You still get support for more than one accelerator key per command. The class takes care of its own registry persistence, and even allows a reset, where all hotkeys are restored to factory defaults (those defined in the accelerator resource). Finally, the hotkey mnemonics that appear on menu items are automatically updated each time you change the accelerator table.可用性方面,该对话框类似于VS6的热键自定义对话框,尽管没有命令类别。您仍然可以获得每个命令多个快捷键的支持。该类负责其自己的注册表持久性,甚至允许重置,其中所有热键都恢复为出厂默认值(在快捷键资源中定义的那些)。最后,每次更改快捷键表时,菜单项上显示的热键助记符都会自动更新。

Background

Command hotkeys are stored in an accelerator table. Most programs have a fixed accelerator table created at design time in a resource editor and loaded when the frame window is created through LoadAccelerators. In WTL, the handle is stored in a member variable of CFrameWindowImplBase, called m_hAccel. The framework does a good job hiding the use of accelerators. The message pump calls TranslateMessage on each retrieved message, and if it happens to correspond to an accelerator key, the equivalent WM_COMMAND is dispatched instead of the keyboard event.命令热键存储在快捷键表中。大多数程序都有一个固定的快捷键表,它在设计时在资源编辑器中创建,并在创建框架窗口时加载LoadAccelerators。在WTL中,句柄存储在一个CFrameWindowImplBase名为的成员变量中m_hAccel。该框架很好地隐藏了快捷键的使用。消息泵对每个检索到的消息调用TranslateMessage,如果它恰好对应于快捷键,WM_COMMAND则调度等效项而不是键盘事件。

In order to offer adjustable hotkeys, an application must comprise:为了提供可调节的热键,申请必须包括:

  • A means to modify the accelerator table on the fly. There is an API called CreateAcceleratorTable that can achieve that with an array of key/command information (ACCEL struct).
  • 一种即时修改快捷键表的方法。有一个被调用的API CreateAcceleratorTable可以使用键/命令信息(ACCELstruct)数组来实现。
  • A way to read key combinations, gratis CHotKeyCtrl system control.一种读取组合键的方法,免费提供CHotKeyCtrl系统控制。
  • Provide user readable hotkey names, through the GetKeyNameText API.通过GetKeyNameTextAPI 提供用户可读的热键名称。

Using these ingredients, changing the hotkeys on the fly involves these steps:使用这些成分,动态更改热键包括以下步骤:

  1. Obtain a copy of the current accelerator table stored in the frame's m_hAccel, using CopyAcceleratorTable.获取存储在框架里的当前快捷键表的副本m_hAccel,使用CopyAcceleratorTable。
  2. Use the provided CKeyAssignDlg to modify the table to taste.使用已提供的CKeyAssignDlg来修改表去尝试。
  3. Destroy the old table and create a new one, setting it to m_hAccel for immediate effect.销毁旧表并创建一个新表,将其设置m_hAccel为立即生效。
  4. Update the menu hotkey mnemonics (and toolbar tooltips) to reflect the current keyboard assignments.更新菜单热键助记符(和工具栏工具提示)以反映当前键盘分配。

That's it! The customized table is stored in a registry key as REG_BINARY. More details can be found in the source code, which demonstrates a minimal WTL SDI application with full hotkey customization support.而已!自定义表存储在注册表项中REG_BINARY。更多细节可以在源代码中找到,它演示了一个具有完整热键定制支持的最小WTL SDI应用程序。

Using the code

The sample code is built using Visual Studio 6, using WTL v7.1 (yes, I am a laggard). I imagine it shouldn't be too hard to build with the latest VS/WTL kit, or even port it to MFC, if you are industrious.

To add keyboard customization to your application, all you need is the main header file keyAssignDlg.h, the dialog IDD_ACCELEDIT_DLG, and a few error message strings from the resources. To integrate it with your project, you need to add a few member variables and message handlers to your main frame window:

示例代码是使用Visual Studio 6使用WTL v7.1构建的(是的,我是落后者)。我想用最新的VS / WTL套件构建起来应该不会太难,或者如果你勤奋的话,甚至可以将它移植到MFC上。

要向应用程序添加键盘自定义,您只需要主要的头文件keyAssignDlg.h,对话框IDD_ACCELEDIT_DLG以及来自资源的一些错误消息字符串。要将它与项目集成,您需要向主框架窗口添加一些成员变量和消息处理程序:

class CMainFrame : public CFrameWindowImpl<CMainFrame>,
public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
public:
//...

void CustomAccelerators();
// call after creation to setup accelerators

BEGIN_MSG_MAP(CMainFrame)
//...

COMMAND_ID_HANDLER(ID_CUSTOMIZE_KEYBOARD, OnCustomizeKeys)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
//...

END_MSG_MAP()

LRESULT OnCustomizeKeys(WORD /*wNotifyCode*/, WORD /*wID*/,
HWND /*hWndCtl*/, BOOL& /*bHandled*/);
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/,
LPARAM /*lParam*/, BOOL& /*bHandled*/);

protected:
CAccelCombo* m_paCustomKeys; // user modified accelerator table (if any)

HACCEL m_hAccelDefault; // original table from resources

};

After WTL's Run handler has successfully created the main frame, call CustomAccelerators to load the custom keys from the registry and store them in the helper class CAccelCombo. We backup the default keys stored in the resources in m_hAccelDefault in case users reset them from the customization dialog. Finally, during destruction, we save the custom accelerator table back to the registry. See the source code for all the juicy details.在WTL的Run处理程序成功创建主框架之后,调用CustomAccelerators从注册表加载自定义键并将它们存储在帮助程序类中CAccelCombo。我们备份存储在资源中的m_hAccelDefault默认键,以防用户从自定义对话框中重置它们。最后,在销毁期间,我们将自定义快捷键表保存回注册表。查看所有多汁细节的源代码。

Points of interest

The really neat feat of this dialog class is the way it populates the categories and the commands. It reuses the structure from your main menu resource. It automatically imports all the information from the resources, and you don't have to type command names and descriptions separately. Not rocket science, but very convenient.

Each top level menu becomes a category, and all its commands (and subcommands) are flattened into a list. Command descriptions are taken from the texts that normally appear on the status bar as you traverse the menu system. This ensures a pleasant and straightforward user experience.

Finally, note that the Windows hotkey control used is not perfect. It passes all key combinations that include ENTERTABSPACEDELESC, or BACKSPACE to DefWindowProc, which makes these keys unavailable for keyboard shortcuts. I tried using WM_GETDLGCODE to eat all keys, without much success. At least, the key names returned by GetKeyNameText are internationalization ready.

这个对话框类的真正优点在于它填充类别和命令的方式。它重用主菜单资源中的结构。它会自动从资源中导入所有信息,您无需单独键入命令名称和说明。不正规,但非常方便。

每个顶级菜单都成为一个类别,其所有命令(和子命令)都被展平为一个列表。当您遍历菜单系统时,命令描述取自通常出现在状态栏上的文本。这确保了愉快和直接的用户体验。

最后,请注意使用的Windows热键控件并不完美。它通过了所有键的组合,其中包括ENTERTABSPACEDELESC空格键来DefWindowProc,这使得这些键的键盘快捷方式不可用。我试着WM_GETDLGCODE用掉所有的键,没有太大的成功。至少,返回的关键名称GetKeyNameText是国际化准备好的。

友情链接
版权所有 Copyright(c)2004-2015 锐英源软件

公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768

地址:郑州市文化路47号院1号楼4层(47-1楼位于文化路和红专路十字路口东北角,郑州大学工学院招待所南边,工学院科技报告厅西边。)