|
|
#include "private.h"
#include "cicsthkl.h"
#define LANGIDFROMHKL(x) LANGID(LOWORD(HandleToLong(x)))
const CHAR c_szCTFTIPKey[] = "SOFTWARE\\Microsoft\\CTF\\TIP\\"; const CHAR c_szLanguageProfileKey[] = "LanguageProfile\\"; const CHAR c_szSubstitutehKL[] = "SubstituteLayout";
//+------------------------------------------------------------------------
//
// Function: cicsthkl_CLSIDToString
//
// Synopsis: Converts a CLSID to an mbcs string.
//
//-------------------------------------------------------------------------
static const BYTE GuidMap[] = {3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-', 8, 9, '-', 10, 11, 12, 13, 14, 15};
static const char szDigits[] = "0123456789ABCDEF";
BOOL cicsthkl_CLSIDToStringA(REFGUID refGUID, char *pchA) { int i; char *p = pchA;
const BYTE * pBytes = (const BYTE *) &refGUID;
*p++ = '{'; for (i = 0; i < sizeof(GuidMap); i++) { if (GuidMap[i] == '-') { *p++ = '-'; } else { *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ]; *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ]; } }
*p++ = '}'; *p = '\0';
return TRUE; }
//+---------------------------------------------------------------------------
//
// cicsthkl_AsciiToNum
//
//----------------------------------------------------------------------------
DWORD cicsthkl_AsciiToNum( char *pszAscii) { DWORD dwNum = 0;
for (; *pszAscii; pszAscii++) { if (*pszAscii >= '0' && *pszAscii <= '9') { dwNum = (dwNum << 4) | (*pszAscii - '0'); } else if (*pszAscii >= 'A' && *pszAscii <= 'F') { dwNum = (dwNum << 4) | (*pszAscii - 'A' + 0x000A); } else if (*pszAscii >= 'a' && *pszAscii <= 'f') { dwNum = (dwNum << 4) | (*pszAscii - 'a' + 0x000A); } else { return (0); } }
return (dwNum); }
//+---------------------------------------------------------------------------
//
// cicsthkl_NumToA
//
//----------------------------------------------------------------------------
void cicsthkl_NumToAscii(DWORD dw, char *psz) { int n = 7; while (n >= 0) { BYTE b = (BYTE)(dw >> (n * 4)) & 0x0F; if (b < 0x0A) *psz = (char)('0' + b); else *psz = (char)('A' + b - 0x0A); psz++; n--; } *psz = L'\0';
return; }
//+---------------------------------------------------------------------------
//
// GetSubstituteHKLFromReg
//
//----------------------------------------------------------------------------
HKL GetSubstituteHKLFromReg(REFCLSID rclsid, LANGID langid, REFGUID rguid) { HKL hKL = NULL; CHAR szKey[MAX_PATH]; CHAR szTempStr[64];
StringCchCopyA(szKey, ARRAYSIZE(szKey), c_szCTFTIPKey); cicsthkl_CLSIDToStringA(rclsid, szTempStr); StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr); StringCchCatA(szKey, ARRAYSIZE(szKey), "\\"); StringCchCatA(szKey, ARRAYSIZE(szKey), c_szLanguageProfileKey); StringCchPrintfA(szTempStr, ARRAYSIZE(szTempStr), "0x%08x", langid); StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr); StringCchCatA(szKey, ARRAYSIZE(szKey), "\\"); cicsthkl_CLSIDToStringA(rguid, szTempStr); StringCchCatA(szKey, ARRAYSIZE(szKey), szTempStr);
HKEY hKey = NULL; LONG lRes = RegOpenKeyExA(HKEY_LOCAL_MACHINE, szKey, 0, KEY_READ, &hKey); if (lRes == ERROR_SUCCESS) { DWORD dwType = NULL; char szValue[32]; DWORD dwCount = sizeof(szValue); lRes = RegQueryValueExA(hKey, (LPTSTR)c_szSubstitutehKL, NULL, &dwType, (LPBYTE)szValue, &dwCount);
if (lRes == ERROR_SUCCESS) { if ((szValue[0] == '0') && ((szValue[1] == 'X') || (szValue[1] == 'x'))) hKL = (HKL)IntToPtr(cicsthkl_AsciiToNum(&szValue[2])); }
RegCloseKey(hKey); } return hKL;
}
//----------------------------------------------------------------------------
//
// [in] langid
// langid may be LOWORD of the return value of GetKeyboardLayout(0).
//
// The return value
// It returns NULL hKL
// - if Cicero does not have a focus
// - it there is no keyboard TIP running now
// - it the current keyboard TIP does not have a substitute layout.
//
//----------------------------------------------------------------------------
HRESULT CicGetSubstitueHKL(LANGID langid, HKL *phkl, BOOL fCheckFocus) { HRESULT hr; ITfThreadMgr *ptim;
*phkl = NULL;
if (fCheckFocus) { BOOL fFocusInCicero = FALSE; if (SUCCEEDED(CoCreateInstance( CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, (void **)&ptim))) { ITfDocumentMgr *pdim; if (SUCCEEDED(ptim->GetFocus(&pdim)) && pdim) { fFocusInCicero = TRUE; pdim->Release(); } ptim->Release(); } if (!fFocusInCicero) { //
// Cicero does not have a focus. Try GetKeyboardLayout(0).
//
return S_FALSE; } } HKL hKL = NULL; ITfInputProcessorProfiles *pPro;
if (SUCCEEDED(hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, (void **)&pPro ))) { CLSID clsid; GUID guid; ITfInputProcessorProfileSubstituteLayout *pProSubLayout;
if (SUCCEEDED(hr = pPro->GetDefaultLanguageProfile(langid, GUID_TFCAT_TIP_KEYBOARD, &clsid, &guid))) { if (!IsEqualGUID(clsid, CLSID_NULL)) { if (SUCCEEDED(hr = pPro->QueryInterface(IID_ITfInputProcessorProfileSubstituteLayout, (void **)&pProSubLayout))) { hr = pProSubLayout->GetSubstituteKeyboardLayout(clsid, langid, guid, &hKL); pProSubLayout->Release(); } else { hKL = GetSubstituteHKLFromReg(clsid, langid, guid); hr = S_OK; } } } pPro->Release(); } //
// if hKL is NULL, please get hKL from GetKeybaordLayout(0).
//
*phkl = hKL; return hr; }
//----------------------------------------------------------------------------
//
// CicSubstGetKeyboardLayout
//
//----------------------------------------------------------------------------
extern "C" HKL WINAPI CicSubstGetKeyboardLayout(char *pszKLID) { HKL hkl = NULL; HKL hklReal = GetKeyboardLayout(0);
if (SUCCEEDED(CicGetSubstitueHKL(LANGIDFROMHKL(hklReal), &hkl, TRUE))) { if (!hkl) { hkl = hklReal; if (pszKLID) GetKeyboardLayoutName(pszKLID); } else { if (pszKLID) cicsthkl_NumToAscii((DWORD)HandleToLong(hkl), pszKLID); } } return hkl; }
//----------------------------------------------------------------------------
//
// CicSubstGetDefaultKeyboardLayout
//
//----------------------------------------------------------------------------
extern "C" HKL WINAPI CicSubstGetDefaultKeyboardLayout(LANGID langid) { HKL hkl = NULL;
CicGetSubstitueHKL(langid, &hkl, FALSE);
return hkl;
}
|