First commit.
This commit is contained in:
commit
7b83802bb2
103 files changed
+19016
No files matched your search
+283
@@ -0,0 +1,283 @@
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
// PARTICULAR PURPOSE.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
|
||||
#include "Private.h"
|
||||
#include "Globals.h"
|
||||
|
||||
static const WCHAR RegInfo_Prefix_CLSID[] = L"CLSID\\";
|
||||
static const WCHAR RegInfo_Key_InProSvr32[] = L"InProcServer32";
|
||||
static const WCHAR RegInfo_Key_ThreadModel[] = L"ThreadingModel";
|
||||
|
||||
static const WCHAR TEXTSERVICE_DESC[] = L"Sample IME";
|
||||
|
||||
static const GUID SupportCategories[] = {
|
||||
GUID_TFCAT_TIP_KEYBOARD,
|
||||
GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER,
|
||||
GUID_TFCAT_TIPCAP_UIELEMENTENABLED,
|
||||
GUID_TFCAT_TIPCAP_SECUREMODE,
|
||||
GUID_TFCAT_TIPCAP_COMLESS,
|
||||
GUID_TFCAT_TIPCAP_INPUTMODECOMPARTMENT,
|
||||
GUID_TFCAT_TIPCAP_IMMERSIVESUPPORT,
|
||||
GUID_TFCAT_TIPCAP_SYSTRAYSUPPORT,
|
||||
};
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// RegisterProfiles
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
BOOL RegisterProfiles()
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
|
||||
ITfInputProcessorProfileMgr *pITfInputProcessorProfileMgr = nullptr;
|
||||
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_ITfInputProcessorProfileMgr, (void**)&pITfInputProcessorProfileMgr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WCHAR achIconFile[MAX_PATH] = {'\0'};
|
||||
DWORD cchA = 0;
|
||||
cchA = GetModuleFileName(Global::dllInstanceHandle, achIconFile, MAX_PATH);
|
||||
cchA = cchA >= MAX_PATH ? (MAX_PATH - 1) : cchA;
|
||||
achIconFile[cchA] = '\0';
|
||||
|
||||
size_t lenOfDesc = 0;
|
||||
hr = StringCchLength(TEXTSERVICE_DESC, STRSAFE_MAX_CCH, &lenOfDesc);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
hr = pITfInputProcessorProfileMgr->RegisterProfile(Global::SampleIMECLSID,
|
||||
TEXTSERVICE_LANGID,
|
||||
Global::SampleIMEGuidProfile,
|
||||
TEXTSERVICE_DESC,
|
||||
static_cast<ULONG>(lenOfDesc),
|
||||
achIconFile,
|
||||
cchA,
|
||||
(UINT)TEXTSERVICE_ICON_INDEX, NULL, 0, TRUE, 0);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if (pITfInputProcessorProfileMgr)
|
||||
{
|
||||
pITfInputProcessorProfileMgr->Release();
|
||||
}
|
||||
|
||||
return (hr == S_OK);
|
||||
}
|
||||
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// UnregisterProfiles
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void UnregisterProfiles()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ITfInputProcessorProfileMgr *pITfInputProcessorProfileMgr = nullptr;
|
||||
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_ITfInputProcessorProfileMgr, (void**)&pITfInputProcessorProfileMgr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
hr = pITfInputProcessorProfileMgr->UnregisterProfile(Global::SampleIMECLSID, TEXTSERVICE_LANGID, Global::SampleIMEGuidProfile, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
Exit:
|
||||
if (pITfInputProcessorProfileMgr)
|
||||
{
|
||||
pITfInputProcessorProfileMgr->Release();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// RegisterCategories
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
BOOL RegisterCategories()
|
||||
{
|
||||
ITfCategoryMgr* pCategoryMgr = nullptr;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr = CoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&pCategoryMgr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for each(GUID guid in SupportCategories)
|
||||
{
|
||||
hr = pCategoryMgr->RegisterCategory(Global::SampleIMECLSID, guid, Global::SampleIMECLSID);
|
||||
}
|
||||
|
||||
pCategoryMgr->Release();
|
||||
|
||||
return (hr == S_OK);
|
||||
}
|
||||
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// UnregisterCategories
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void UnregisterCategories()
|
||||
{
|
||||
ITfCategoryMgr* pCategoryMgr = S_OK;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr = CoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&pCategoryMgr);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for each(GUID guid in SupportCategories)
|
||||
{
|
||||
pCategoryMgr->UnregisterCategory(Global::SampleIMECLSID, guid, Global::SampleIMECLSID);
|
||||
}
|
||||
|
||||
pCategoryMgr->Release();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// RecurseDeleteKey
|
||||
//
|
||||
// RecurseDeleteKey is necessary because on NT RegDeleteKey doesn't work if the
|
||||
// specified key has subkeys
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
LONG RecurseDeleteKey(_In_ HKEY hParentKey, _In_ LPCTSTR lpszKey)
|
||||
{
|
||||
HKEY regKeyHandle = nullptr;
|
||||
LONG res = 0;
|
||||
FILETIME time;
|
||||
WCHAR stringBuffer[256] = {'\0'};
|
||||
DWORD size = ARRAYSIZE(stringBuffer);
|
||||
|
||||
if (RegOpenKey(hParentKey, lpszKey, ®KeyHandle) != ERROR_SUCCESS)
|
||||
{
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
res = ERROR_SUCCESS;
|
||||
while (RegEnumKeyEx(regKeyHandle, 0, stringBuffer, &size, NULL, NULL, NULL, &time) == ERROR_SUCCESS)
|
||||
{
|
||||
stringBuffer[ARRAYSIZE(stringBuffer)-1] = '\0';
|
||||
res = RecurseDeleteKey(regKeyHandle, stringBuffer);
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
size = ARRAYSIZE(stringBuffer);
|
||||
}
|
||||
RegCloseKey(regKeyHandle);
|
||||
|
||||
return res == ERROR_SUCCESS ? RegDeleteKey(hParentKey, lpszKey) : res;
|
||||
}
|
||||
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// RegisterServer
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
BOOL RegisterServer()
|
||||
{
|
||||
DWORD copiedStringLen = 0;
|
||||
HKEY regKeyHandle = nullptr;
|
||||
HKEY regSubkeyHandle = nullptr;
|
||||
BOOL ret = FALSE;
|
||||
WCHAR achIMEKey[ARRAYSIZE(RegInfo_Prefix_CLSID) + CLSID_STRLEN] = {'\0'};
|
||||
WCHAR achFileName[MAX_PATH] = {'\0'};
|
||||
|
||||
if (!CLSIDToString(Global::SampleIMECLSID, achIMEKey + ARRAYSIZE(RegInfo_Prefix_CLSID) - 1))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(achIMEKey, RegInfo_Prefix_CLSID, sizeof(RegInfo_Prefix_CLSID) - sizeof(WCHAR));
|
||||
|
||||
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, achIMEKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, ®KeyHandle, &copiedStringLen) == ERROR_SUCCESS)
|
||||
{
|
||||
if (RegSetValueEx(regKeyHandle, NULL, 0, REG_SZ, (const BYTE *)TEXTSERVICE_DESC, (_countof(TEXTSERVICE_DESC))*sizeof(WCHAR)) != ERROR_SUCCESS)
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (RegCreateKeyEx(regKeyHandle, RegInfo_Key_InProSvr32, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, ®SubkeyHandle, &copiedStringLen) == ERROR_SUCCESS)
|
||||
{
|
||||
copiedStringLen = GetModuleFileNameW(Global::dllInstanceHandle, achFileName, ARRAYSIZE(achFileName));
|
||||
copiedStringLen = (copiedStringLen >= (MAX_PATH - 1)) ? MAX_PATH : (++copiedStringLen);
|
||||
if (RegSetValueEx(regSubkeyHandle, NULL, 0, REG_SZ, (const BYTE *)achFileName, (copiedStringLen)*sizeof(WCHAR)) != ERROR_SUCCESS)
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
if (RegSetValueEx(regSubkeyHandle, RegInfo_Key_ThreadModel, 0, REG_SZ, (const BYTE *)TEXTSERVICE_MODEL, (_countof(TEXTSERVICE_MODEL)) * sizeof(WCHAR)) != ERROR_SUCCESS)
|
||||
{
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
if (regSubkeyHandle)
|
||||
{
|
||||
RegCloseKey(regSubkeyHandle);
|
||||
regSubkeyHandle = nullptr;
|
||||
}
|
||||
if (regKeyHandle)
|
||||
{
|
||||
RegCloseKey(regKeyHandle);
|
||||
regKeyHandle = nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//+---------------------------------------------------------------------------
|
||||
//
|
||||
// UnregisterServer
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void UnregisterServer()
|
||||
{
|
||||
WCHAR achIMEKey[ARRAYSIZE(RegInfo_Prefix_CLSID) + CLSID_STRLEN] = {'\0'};
|
||||
|
||||
if (!CLSIDToString(Global::SampleIMECLSID, achIMEKey + ARRAYSIZE(RegInfo_Prefix_CLSID) - 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(achIMEKey, RegInfo_Prefix_CLSID, sizeof(RegInfo_Prefix_CLSID) - sizeof(WCHAR));
|
||||
|
||||
RecurseDeleteKey(HKEY_CLASSES_ROOT, achIMEKey);
|
||||
}
|
||||
Reference in new issue
Block a user