/* Name: hotkeys Copyright: Copyright (C) SIL International. Documentation: Description: Create Date: 1 Aug 2006 Modified Date: 25 Oct 2016 Authors: mcdurdin Related Files: Dependencies: Bugs: Todo: Notes: History: 01 Aug 2006 - mcdurdin - Initial version 11 Dec 2009 - mcdurdin - I934 - x64 - Initial version 12 Mar 2010 - mcdurdin - I934 - x64 - Complete 03 Aug 2014 - mcdurdin - I4326 - V9.0 - Switch-off hotkey not working, then keyboard hotkey stopped working (win 8.1 jeremy) [High] 28 Aug 2014 - mcdurdin - I4390 - V9.0 - Free vs Pro 13 Oct 2014 - mcdurdin - I4451 - V9.0 - Language hotkeys are not working 14 Nov 2014 - mcdurdin - I4516 - V9.0 - Language hotkeys associated with non-primary keyboards do not trigger language change 27 Mar 2015 - mcdurdin - I4641 - V9.0 - Keyman can crash silently on exit due to null hotkeys being addressed 25 Oct 2016 - mcdurdin - I5136 - Remove additional product references from Keyman Engine */ // I5136 #include "pch.h" #ifdef _WIN64 #error hotkeys.cpp is not required for win64. #endif Hotkeys *g_Hotkeys = NULL; // I4326 Hotkeys *Hotkeys::Instance() { // I4326 if(GetCurrentThreadId() != Globals::get_InitialisingThread()) { return NULL; // Will bork on other threads given current usage :) } if(g_Hotkeys == NULL) { g_Hotkeys = new Hotkeys; g_Hotkeys->Load(); // I4390 } return g_Hotkeys; } void Hotkeys::Unload() { if (GetCurrentThreadId() != Globals::get_InitialisingThread()) { OutputThreadDebugString("Unexpected: no other thread should be attempting to unload hotkeys"); return; } if (g_Hotkeys != NULL) { delete g_Hotkeys; g_Hotkeys = NULL; } } void Hotkeys::Reload() { // I4326 // I4390 Hotkeys *hotkeys = Hotkeys::Instance(); // I4641 if(hotkeys == NULL) { return; } hotkeys->Load(); // I4390 } void Hotkeys::Load() { // I4390 SendDebugMessageFormat(0, sdmGlobal, 0, "Hotkeys::Load() enter"); m_nHotkeys = 0; RegistryReadOnly reg(HKEY_CURRENT_USER); /* Load interface hotkeys */ if(reg.OpenKeyReadOnly(REGSZ_KeymanHotkeys)) { int n = 0; char name[128]; while(reg.GetValueNames(name, 128, n++)) { m_hotkeys[m_nHotkeys].HotkeyType = hktInterface; m_hotkeys[m_nHotkeys].HotkeyValue = reg.ReadInteger(name); m_hotkeys[m_nHotkeys].Target = atoi(name); SendDebugMessageFormat(0, sdmGlobal, 0, "InterfaceHotkey[%d] = {HotkeyValue: %x, Target: %d}", m_nHotkeys, m_hotkeys[m_nHotkeys].HotkeyValue, m_hotkeys[m_nHotkeys].Target); if(++m_nHotkeys >= MAX_HOTKEYS) { break; } } } reg.CloseKey(); if(m_nHotkeys >= MAX_HOTKEYS) { return; } /* Load language hotkeys */ // I4451 if(reg.OpenKeyReadOnly(REGSZ_KeymanLanguageHotkeys)) { int nkey = 0; WCHAR valuename[128]; while(reg.GetValueNames(valuename, 128, nkey++)) { m_hotkeys[m_nHotkeys].HotkeyType = hktLanguage; m_hotkeys[m_nHotkeys].hkl = (HKL) wcstoul(valuename, NULL, 16); // I4516 if(m_hotkeys[m_nHotkeys].hkl == 0) { // Will be a guid if(!SUCCEEDED(CLSIDFromString(valuename, &m_hotkeys[m_nHotkeys].profileGUID))) { continue; } } WCHAR hkval[64]; reg.ReadString(valuename, hkval, 64); m_hotkeys[m_nHotkeys].HotkeyValue = _wtoi(hkval); SendDebugMessageFormat(0, sdmGlobal, 0, "LanguageHotkey[%d] = {HotkeyValue: %x, hkl: %x, profileGUID: %ws}", m_nHotkeys, m_hotkeys[m_nHotkeys].HotkeyValue, m_hotkeys[m_nHotkeys].hkl, m_hotkeys[m_nHotkeys].hkl == 0 ? valuename : L""); if(++m_nHotkeys >= MAX_HOTKEYS) { break; } } } reg.CloseKey(); SendDebugMessageFormat(0, sdmGlobal, 0, "Hotkeys::Load() exit"); } Hotkey *Hotkeys::GetHotkey(DWORD hotkey) { for(int i = 0; i < m_nHotkeys; i++) if(m_hotkeys[i].HotkeyValue == hotkey) return &m_hotkeys[i]; return NULL; }