Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

721 lines
21 KiB

#include "private.h"
#include <stdio.h>
#include <stdlib.h>
#include "HKLHelp.h"
// Safe String
#define STRSAFE_NO_DEPRECATE
#include "strsafe.h"
extern BOOL WINAPI IsNT();
typedef char KeyNameType[MAX_NAME];
// Forward decls.
static void SortRegKeys(KeyNameType *hKLKeyList, KeyNameType *hKLList, INT Num);
static void RenumberPreload(HKEY hKeyCU);
static void SwitcHKLtoIME61();
static BOOL CALLBACK EnumChildProcForSwitchKL(HWND hWnd, LPARAM lParam);
static BOOL CALLBACK EnumProcForSwitchKL(HWND hWnd, LPARAM lParam);
/*---------------------------------------------------------------------------
GetHKLfromHKLM
---------------------------------------------------------------------------*/
HKL GetHKLfromHKLM(LPSTR argszIMEFile)
{
HKL hklAnswer = 0;
HKEY hKey, hSubKey;
DWORD i, cbSubKey, cbIMEFile;
TCHAR szSubKey[MAX_PATH], szIMEFile[MAX_PATH];
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Keyboard Layouts", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
for (i=0; ;i++)
{
cbSubKey = MAX_PATH;
if (RegEnumKeyEx(hKey, i, szSubKey, &cbSubKey, NULL, NULL, NULL, NULL) == ERROR_NO_MORE_ITEMS)
break;
RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey);
cbIMEFile=MAX_PATH;
if (RegQueryValueEx(hSubKey,"IME File",NULL,NULL,(LPBYTE)szIMEFile, &cbIMEFile) == ERROR_SUCCESS)
{
if (lstrcmpi(argszIMEFile, szIMEFile) == 0)
{
RegCloseKey(hSubKey);
sscanf(szSubKey, "%08x", &hklAnswer);
break;
}
}
RegCloseKey(hSubKey);
}
RegCloseKey(hKey);
}
return(hklAnswer);
}
/*---------------------------------------------------------------------------
GetDefaultIMEFromHKCU
---------------------------------------------------------------------------*/
HKL GetDefaultIMEFromHKCU(HKEY hKeyCU)
{
HKEY hKey;
DWORD cbData;
BYTE Data[MAX_NAME];
HKL hKL = 0;
cbData=sizeof(Data);
if (IsNT())
{
RegOpenKeyEx(hKeyCU, "Keyboard Layout\\Preload", 0, KEY_READ, &hKey);
RegQueryValueEx(hKey, "1", 0, NULL, Data, &cbData);
RegCloseKey(hKey);
}
else
{ // Case of non-NT
RegOpenKeyEx(hKeyCU, "keyboard layout\\preload\\1", 0, KEY_READ, &hKey);
RegQueryValueEx(hKey, "", 0, NULL, Data, &cbData);
RegCloseKey(hKey);
}
sscanf((const char *)Data,"%08x",&hKL);
return(hKL);
}
/*---------------------------------------------------------------------------
HKLHelpExistInPreload
---------------------------------------------------------------------------*/
BOOL HKLHelpExistInPreload(HKEY hKeyCU, HKL hKL)
{
HKEY hKey,hSubKey;
CHAR szKL[20];
int i,j;
DWORD cbName,cbData;
CHAR Name[MAX_NAME];
BYTE Data[MAX_NAME];
FILETIME ftLastWriteTime;
BOOL fResult = FALSE;
wsprintf(szKL,"%08x",hKL);
if (IsNT())
{
if (RegOpenKeyEx(hKeyCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
for (j=0; cbName=MAX_NAME, cbData=MAX_NAME, RegEnumValue(hKey, j, Name, &cbName, NULL, NULL, Data, &cbData) != ERROR_NO_MORE_ITEMS; j++)
{
if (lstrcmpi((LPCSTR)Data, szKL) == 0)
{
fResult = TRUE;
break;
}
}
RegCloseKey(hKey);
}
}
else
{ // Case of non-NT
if (RegOpenKeyEx(hKeyCU, "keyboard layout\\preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
for (i=0; cbName=MAX_NAME, RegEnumKeyEx(hKey, i, Name, &cbName, 0, NULL, NULL, &ftLastWriteTime) != ERROR_NO_MORE_ITEMS; i++)
{
RegOpenKeyEx(hKey, Name, 0, KEY_ALL_ACCESS, &hSubKey);
cbData=MAX_NAME;
RegQueryValueEx(hSubKey, "", 0, NULL, Data, &cbData);
RegCloseKey(hSubKey);
if (lstrcmpi((LPCSTR)Data, szKL) == 0)
{
fResult = TRUE;
break;
}
}
RegCloseKey(hKey);
}
}
return(fResult);
}
/*---------------------------------------------------------------------------
HKLHelp412ExistInPreload
---------------------------------------------------------------------------*/
BOOL HKLHelp412ExistInPreload(HKEY hKeyCU)
{
HKEY hKey, hSubKey;
int i ,j;
DWORD cbName, cbData;
CHAR szName[MAX_NAME];
CHAR szData[MAX_NAME];
HKL hkl;
FILETIME ftLastWriteTime;
BOOL fResult = FALSE;
if (IsNT())
{
if (RegOpenKeyEx(hKeyCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
for (j=0; cbName=MAX_NAME, cbData=MAX_NAME, RegEnumValue(hKey, j, szName, &cbName, NULL, NULL, (LPBYTE)szData, &cbData) != ERROR_NO_MORE_ITEMS; j++)
{
// See If Korean KL exist. Just compare last LCID part if it's 0x412.
// IME hkl set 0xE000 on hiword.
sscanf(szData, "%08x", &hkl);
if ((HIWORD(hkl) & 0xe000) && LOWORD(hkl) == 0x0412)
{
fResult = TRUE;
break;
}
}
RegCloseKey(hKey);
}
}
else
{ // Case of non-NT
if (RegOpenKeyEx(hKeyCU, "keyboard layout\\preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
for (i=0; cbName=MAX_NAME, RegEnumKeyEx(hKey, i, szName, &cbName, 0, NULL, NULL, &ftLastWriteTime) != ERROR_NO_MORE_ITEMS; i++)
{
RegOpenKeyEx(hKey, szName, 0, KEY_ALL_ACCESS, &hSubKey);
cbData=MAX_NAME;
RegQueryValueEx(hSubKey, "", 0, NULL, (LPBYTE)szData, &cbData);
RegCloseKey(hSubKey);
sscanf(szData, "%08x", &hkl);
if ((HIWORD(hkl) & 0xe000) && LOWORD(hkl) == 0x0412)
{
fResult = TRUE;
break;
}
}
RegCloseKey(hKey);
}
}
return(fResult);
}
/*---------------------------------------------------------------------------
HKLHelpRemoveFromPreload
---------------------------------------------------------------------------*/
void HKLHelpRemoveFromPreload(HKEY hKeyCU, HKL hKL)
{
HKEY hKey,hSubKey;
char szKL[20];
int i, j;
DWORD cbName,cbData;
CHAR szName[MAX_NAME];
BYTE Data[MAX_NAME];
FILETIME ftLastWriteTime;
wsprintf(szKL, "%08x", hKL);
if (IsNT())
{
if (RegOpenKeyEx(hKeyCU,"Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
for (j=0; ; j++)
{
cbName = MAX_NAME;
cbData = MAX_NAME;
if (RegEnumValue(hKey, j, szName, &cbName, NULL, NULL, Data, &cbData) == ERROR_NO_MORE_ITEMS )
break;
if (lstrcmpi((const char *)Data,szKL) == 0)
{
RegDeleteValue(hKey, szName);
break;
}
}
RegCloseKey(hKey);
}
}
else
{
if (RegOpenKeyEx(hKeyCU,"keyboard layout\\preload", 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
for (i=0; ; i++)
{
cbName = MAX_NAME;
if (RegEnumKeyEx(hKey, i, szName, &cbName, 0, NULL, NULL, &ftLastWriteTime) == ERROR_NO_MORE_ITEMS)
break;
RegOpenKeyEx(hKey, szName, 0, KEY_ALL_ACCESS, &hSubKey);
cbData = MAX_NAME;
RegQueryValueEx(hSubKey, "", 0, NULL, Data, &cbData);
RegCloseKey(hSubKey);
if (lstrcmpi((const char *)Data,szKL) == 0)
{
RegDeleteKey(hKey, szName);
break;
}
}
RegCloseKey(hKey);
}
}
RenumberPreload(hKeyCU);
}
/*---------------------------------------------------------------------------
HKLHelpRemoveFromControlSet
---------------------------------------------------------------------------*/
void HKLHelpRemoveFromControlSet(HKL hKL)
{
HKEY hKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,"System\\CurrentControlSet\\control\\keyboard layouts",0,KEY_ALL_ACCESS,&hKey) == ERROR_SUCCESS)
{
CHAR szKeyName[10];
wsprintf(szKeyName, "%08x", hKL);
RegDeleteKey(hKey, szKeyName);
RegCloseKey(hKey);
}
}
/*---------------------------------------------------------------------------
HKLHelpRegisterIMEwithForcedHKL
---------------------------------------------------------------------------*/
void HKLHelpRegisterIMEwithForcedHKL(HKL hKL, LPSTR szIMEFile, LPSTR szTitle)
{
CHAR szRegPath[MAX_PATH];
DWORD dwDisposition;
HKEY hKey;
CHAR szIMEFileUpper[MAX_PATH];
for (INT i = 0; szIMEFile[i] != 0; i++)
szIMEFileUpper[i] = (CHAR)toupper(szIMEFile[i]);
szIMEFileUpper[i] = 0;
wsprintf(szRegPath, "System\\CurrentControlSet\\Control\\Keyboard Layouts\\%08x", hKL);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS)
{
RegSetValueEx(hKey, "Ime File", 0, REG_SZ, (LPBYTE)szIMEFileUpper, lstrlen(szIMEFile)+1);
RegSetValueEx(hKey, "Layout Text", 0, REG_SZ, (LPBYTE)szTitle, lstrlen(szTitle)+1);
RegCloseKey(hKey);
}
}
/*---------------------------------------------------------------------------
HKLHelpGetLayoutString
---------------------------------------------------------------------------*/
void HKLHelpGetLayoutString(HKL hKL, LPSTR szLayoutString, DWORD *pcbSize)
{
CHAR szRegPath[MAX_PATH];
HKEY hKey;
wsprintf(szRegPath, "System\\CurrentControlSet\\Control\\Keyboard Layouts\\%08x", hKL);
if(ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegPath, 0, KEY_READ, &hKey))
{
RegQueryValueEx(hKey, "Layout Text", NULL, NULL, (LPBYTE)szLayoutString, pcbSize);
RegCloseKey(hKey);
}
}
/*---------------------------------------------------------------------------
HKLHelpSetDefaultKeyboardLayout
---------------------------------------------------------------------------*/
void HKLHelpSetDefaultKeyboardLayout(HKEY hKeyHKCU, HKL hKL, BOOL fSetToDefault)
{
char szKL[20];
BYTE Data[MAX_PATH];
DWORD cbData;
char szSubKey[MAX_PATH];
HKEY hKey,hSubKey;
DWORD NumKL;
wsprintf(szKL, "%08x", hKL);
if (IsNT())
{
RegOpenKeyEx(hKeyHKCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey);
if (hKey != NULL)
{
RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &NumKL, NULL, NULL, NULL, NULL);
for (DWORD i=0; i<NumKL; i++)
{
wsprintf(szSubKey, "%d", i+1);
cbData = MAX_PATH;
RegQueryValueEx(hKey, szSubKey, NULL, NULL, Data, &cbData);
if (lstrcmpi((const char *)Data, szKL) == 0)
break;
}
// if hKL is not exist create it.
if (NumKL == i)
{
wsprintf(szSubKey,"%d",i+1);
RegSetValueEx(hKey, szSubKey, 0, REG_SZ, (const unsigned char *)szKL, lstrlen(szKL)+1);
NumKL++;
}
// Set hKL as first, Shift down other.
if(fSetToDefault)
{
for(int j=i; j>0; j--)
{
wsprintf(szSubKey,"%d",j);
cbData = MAX_PATH;
RegQueryValueEx(hKey, szSubKey, NULL, NULL, Data, &cbData);
wsprintf(szSubKey,"%d",j+1);
RegSetValueEx(hKey, szSubKey, 0, REG_SZ, Data, cbData);
}
RegSetValueEx(hKey, "1", 0, REG_SZ, (const unsigned char *)szKL, lstrlen(szKL)+1);
}
RegCloseKey(hKey);
}
}
else
{
RegOpenKeyEx(hKeyHKCU, "Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey);
if (hKey != NULL)
{
RegQueryInfoKey(hKey, NULL, NULL, NULL, &NumKL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
for (DWORD i=0; i<NumKL; i++)
{
wsprintf(szSubKey, "%d", i+1);
RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
cbData = MAX_PATH;
RegQueryValueEx(hSubKey, "", NULL, NULL, Data, &cbData);
if (lstrcmpi((const char *)Data, szKL) == 0)
break;
RegCloseKey(hSubKey);
}
if (NumKL == i)
{
wsprintf(szSubKey,"%d",i+1);
RegCreateKeyEx(hKey,szSubKey,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hSubKey,NULL);
RegSetValueEx(hSubKey,"",0,REG_SZ,(const unsigned char *)szKL,lstrlen(szKL)+1);
RegCloseKey(hSubKey);
NumKL++;
}
if(fSetToDefault)
{
for (int j=i; j>0; j--)
{
wsprintf(szSubKey, "%d", j);
RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
cbData = MAX_PATH;
RegQueryValueEx(hSubKey, "", NULL, NULL, Data, &cbData);
RegCloseKey(hSubKey);
wsprintf(szSubKey,"%d",j+1);
RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
cbData = MAX_PATH;
RegSetValueEx(hSubKey, "", 0, REG_SZ, Data, cbData);
RegCloseKey(hSubKey);
}
RegOpenKeyEx(hKey, "1", 0, KEY_ALL_ACCESS, &hSubKey);
RegSetValueEx(hSubKey, "", 0, REG_SZ, (const LPBYTE)szKL, lstrlen(szKL)+1);
RegCloseKey(hSubKey);
}
RegCloseKey(hKey);
}
}
(void)LoadKeyboardLayout(szKL, KLF_ACTIVATE | KLF_SETFORPROCESS);
// To activate IME2002 right now without reboot.
if(fSetToDefault)
{
(void)SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, (HKL*)&hKL, SPIF_SENDCHANGE);
SwitcHKLtoIME61();
}
}
/*---------------------------------------------------------------------------
SetDefaultKeyboardLayout
---------------------------------------------------------------------------*/
void SetDefaultKeyboardLayoutForDefaultUser(const HKL hKL)
{
char szKL[20];
HKEY hKey, hSubKey;
wsprintf(szKL,"%08x",hKL);
if (!IsNT())
{
// Win9x has only one preload.
RegOpenKeyEx(HKEY_USERS, ".Default\\Keyboard Layout\\Preload", 0, KEY_ALL_ACCESS, &hKey);
RegOpenKeyEx(hKey, "1", 0, KEY_ALL_ACCESS, &hSubKey);
RegSetValueEx(hSubKey, "", 0, REG_SZ, (const LPBYTE)szKL, lstrlen(szKL)+1);
RegCloseKey(hSubKey);
RegCloseKey(hKey);
}
}
/*---------------------------------------------------------------------------
AddPreload
Add IME2002 to preload in given HKCU tree.
If there's other old MS-IMEs, remove them from preload.
If Korean keyboard layout was the default keyboard layout,
set IME2002 as default keyboard layout.
Given HKCU usually can be HKEY_CURRENT_USER or HKEY_USERS\.Default.
---------------------------------------------------------------------------*/
BOOL AddPreload(HKEY hKeyCU, HKL hKL)
{
BOOL fKoreanWasDefault = fFalse;
HKL hDefaultKL, hKLOldMSIME;
// If there is no Kor IME exist in preload, we shouldn't add Kor IME.
if (!HKLHelp412ExistInPreload(hKeyCU))
return FALSE;
hDefaultKL = GetDefaultIMEFromHKCU(hKeyCU);
if (LOWORD(hDefaultKL) == 0x0412)
fKoreanWasDefault = fTrue;
// Win95 IME
hKLOldMSIME = GetHKLfromHKLM("msime95.ime");
if (hKLOldMSIME)
{
HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
RegFlushKey(hKeyCU);
UnloadKeyboardLayout(hKLOldMSIME);
}
// NT4 IME
hKLOldMSIME = GetHKLfromHKLM("msime95k.ime");
if(NULL != hKLOldMSIME)
{
HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
RegFlushKey(hKeyCU);
UnloadKeyboardLayout(hKLOldMSIME);
}
// Win98, ME, NT4 SP6 & W2K IME
hKLOldMSIME = GetHKLfromHKLM("imekr98u.ime");
if(NULL != hKLOldMSIME)
{
HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
RegFlushKey(hKeyCU);
UnloadKeyboardLayout(hKLOldMSIME);
}
// Office 10 IME(6.0)
hKLOldMSIME = GetHKLfromHKLM("imekr.ime");
if(NULL != hKLOldMSIME)
{
HKLHelpRemoveFromPreload(hKeyCU, hKLOldMSIME);
RegFlushKey(hKeyCU);
UnloadKeyboardLayout(hKLOldMSIME);
}
if (hKL && hKL != hDefaultKL)
HKLHelpSetDefaultKeyboardLayout(hKeyCU, hKL, fKoreanWasDefault);
return (fKoreanWasDefault);
}
//////////////////////////////////////////////////////////////////////////////
// Private functions
void SortRegKeys(KeyNameType *hKLKeyList, KeyNameType *hKLList, INT Num)
{
KeyNameType hKeyTmp;
INT PhaseCur, PhaseEnd;
for (PhaseEnd=0; PhaseEnd < Num-1; PhaseEnd++)
{
for (PhaseCur = Num-1; PhaseCur > PhaseEnd; PhaseCur--)
{
if(atoi(hKLKeyList[PhaseCur]) < atoi(hKLKeyList[PhaseCur-1]))
{
StringCchCopy(hKeyTmp, MAX_NAME, hKLKeyList[PhaseCur-1]);
StringCchCopy(hKLKeyList[PhaseCur-1], MAX_NAME, hKLKeyList[PhaseCur]);
StringCchCopy(hKLKeyList[PhaseCur], MAX_NAME, hKeyTmp);
StringCchCopy(hKeyTmp, MAX_NAME, hKLList[PhaseCur-1]);
StringCchCopy(hKLList[PhaseCur-1], MAX_NAME, hKLList[PhaseCur]);
StringCchCopy(hKLList[PhaseCur], MAX_NAME, hKeyTmp);
}
}
}
}
void RenumberPreload(HKEY hKeyCU)
{
int i, j, k;
DWORD cbName,cbData;
char Name[MAX_NAME];
BYTE Data[MAX_NAME];
FILETIME ftLastWriteTime;
HKEY hKey,hSubKey;
char szNum[10];
DWORD dwDisposition,MaxValue;
KeyNameType *hKLKeyList,*hKLList;
if(IsNT())
{
RegOpenKeyEx(hKeyCU,"keyboard layout\\preload",0,KEY_ALL_ACCESS,&hKey);
if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &MaxValue, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return;
}
hKLKeyList = (KeyNameType *)GlobalAllocPtr(GHND, sizeof(KeyNameType)*MaxValue);
if (hKLKeyList == NULL)
{
RegCloseKey(hKey);
return;
}
hKLList = (KeyNameType *)GlobalAllocPtr(GHND, sizeof(KeyNameType)*MaxValue);
if (hKLList == NULL)
{
GlobalFreePtr(hKLKeyList);
RegCloseKey(hKey);
return;
}
for (j=0; ;j++)
{
cbName = MAX_NAME;
cbData = MAX_NAME;
if (RegEnumValue(hKey, j, Name, &cbName, NULL, NULL, Data, &cbData) == ERROR_NO_MORE_ITEMS)
break;
StringCchCopy(hKLList[j], MAX_NAME, (const char *)Data);
StringCchCopy(hKLKeyList[j], MAX_NAME, Name);
}
for (k=0; k<j; k++)
RegDeleteValue(hKey, hKLKeyList[k]);
SortRegKeys(hKLKeyList, hKLList, j);
for (k=0; k<j; k++)
{
wsprintf(szNum,"%d",k+1);
RegSetValueEx(hKey, szNum, 0, REG_SZ, (const unsigned char *)hKLList[k], lstrlen(hKLList[k])+1);
}
RegCloseKey(hKey);
GlobalFreePtr(hKLList);
GlobalFreePtr(hKLKeyList);
}
else
{
RegOpenKeyEx(hKeyCU,"keyboard layout\\preload",0,KEY_ALL_ACCESS,&hKey);
if (RegQueryInfoKey(hKey, NULL, NULL, NULL, &MaxValue, NULL, NULL,NULL,NULL,NULL,NULL,NULL) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return;
}
hKLKeyList = (KeyNameType *)GlobalAllocPtr(GHND,sizeof(KeyNameType)*MaxValue);
hKLList = (KeyNameType *)GlobalAllocPtr(GHND,sizeof(KeyNameType)*MaxValue);
if (hKLKeyList == NULL || hKLList == NULL)
return;
for (i=0; ;i++)
{
cbName = MAX_NAME;
if (RegEnumKeyEx(hKey, i, Name, &cbName, 0, NULL, NULL, &ftLastWriteTime) == ERROR_NO_MORE_ITEMS)
break;
RegOpenKeyEx(hKey, Name, 0, KEY_ALL_ACCESS, &hSubKey);
cbData = MAX_NAME;
RegQueryValueEx(hSubKey, "", 0, NULL, Data, &cbData);
RegCloseKey(hSubKey);
StringCchCopy(hKLList[i], MAX_NAME, (const char *)Data);
StringCchCopy(hKLKeyList[i], MAX_NAME, Name);
}
for(k=0; k<i; k++)
RegDeleteKey(hKey, hKLKeyList[k]);
SortRegKeys(hKLKeyList, hKLList, i);
for(k=0; k<i; k++)
{
wsprintf(szNum,"%d",k+1);
RegCreateKeyEx(hKey, szNum, 0, "",REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hSubKey, &dwDisposition);
RegSetValueEx(hSubKey, "", 0, REG_SZ, (const unsigned char *)hKLList[k], lstrlen(hKLList[k])+1);
RegCloseKey(hSubKey);
}
RegCloseKey(hKey);
GlobalFreePtr(hKLList);
GlobalFreePtr(hKLKeyList);
}
}
BOOL CALLBACK EnumChildProcForSwitchKL(HWND hWnd, LPARAM lParam)
{
if (TRUE/*IsWindowVisible( hWnd )*/)
{
HKL hKL = (HKL)lParam;
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 1/*INPUTLANGCHANGE_SYSCHARSET*/, (LPARAM)hKL); // change kl to IME8.1
}
return TRUE;
}
BOOL CALLBACK EnumProcForSwitchKL(HWND hWnd, LPARAM lParam)
{
if (TRUE/*IsWindowVisible( hWnd )*/)
{
HKL hKL = (HKL)lParam;
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 1/*INPUTLANGCHANGE_SYSCHARSET*/, (LPARAM)hKL);
// try child windows
EnumChildWindows(hWnd, EnumChildProcForSwitchKL, lParam);
}
return TRUE;
}
void SwitcHKLtoIME61()
{
HKL hKL = NULL;
HWND hWnd = NULL;
//
// switch hKL to IME6.1
//
hKL = GetHKLfromHKLM(TEXT("imekr61.ime")); // find IME6.1 kl
if (hKL != NULL)
{
//
// desktop (special)
//
hWnd = FindWindow("Progman", NULL); // find desktop window
if (hWnd!= NULL)
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 1/*INPUTLANGCHANGE_SYSCHARSET*/, (LPARAM)hKL);
//
// generic enum
//
EnumWindows(EnumProcForSwitchKL, (LPARAM)hKL);
}
}