mirror of
https://github.com/reactos/reactos.git
synced 2025-05-19 17:14:32 +00:00
[MSCTFIME][SDK] Implement CtfImeSelectEx (#6238)
Supporting TIPs... JIRA issue: CORE-19360 - Add GetCharsetFromLangId and InternalSelectEx helper functions. - Add CicBridge::GetInputContext and CicBridge::SelectEx. - Implement CtfImeSelectEx function. - CTFIMECONTEXT structure moved into <cicero/cicimc.h>.
This commit is contained in:
parent
d528cc4013
commit
73a1c9d418
3 changed files with 250 additions and 10 deletions
|
@ -81,6 +81,9 @@ BOOL RegisterMSIMEMessage(VOID)
|
||||||
|
|
||||||
typedef BOOLEAN (WINAPI *FN_DllShutDownInProgress)(VOID);
|
typedef BOOLEAN (WINAPI *FN_DllShutDownInProgress)(VOID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
EXTERN_C BOOLEAN WINAPI
|
EXTERN_C BOOLEAN WINAPI
|
||||||
DllShutDownInProgress(VOID)
|
DllShutDownInProgress(VOID)
|
||||||
{
|
{
|
||||||
|
@ -99,6 +102,9 @@ DllShutDownInProgress(VOID)
|
||||||
return s_fnDllShutDownInProgress();
|
return s_fnDllShutDownInProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
static BOOL
|
static BOOL
|
||||||
IsInteractiveUserLogon(VOID)
|
IsInteractiveUserLogon(VOID)
|
||||||
{
|
{
|
||||||
|
@ -136,6 +142,9 @@ HRESULT InitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
||||||
{
|
{
|
||||||
if (!pLibThread)
|
if (!pLibThread)
|
||||||
|
@ -150,6 +159,86 @@ HRESULT UninitDisplayAttrbuteLib(PCIC_LIBTHREAD pLibThread)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
BYTE GetCharsetFromLangId(DWORD dwValue)
|
||||||
|
{
|
||||||
|
CHARSETINFO info;
|
||||||
|
if (!::TranslateCharsetInfo((DWORD*)(DWORD_PTR)dwValue, &info, TCI_SRCLOCALE))
|
||||||
|
return 0;
|
||||||
|
return info.ciCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
HRESULT
|
||||||
|
InternalSelectEx(HIMC hIMC, BOOL fSelect, LANGID LangID)
|
||||||
|
{
|
||||||
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (!imcLock)
|
||||||
|
imcLock.m_hr = E_FAIL;
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
if (PRIMARYLANGID(LangID) == LANG_CHINESE)
|
||||||
|
{
|
||||||
|
imcLock.get().cfCandForm[0].dwStyle = 0;
|
||||||
|
imcLock.get().cfCandForm[0].dwIndex = (DWORD)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fSelect)
|
||||||
|
{
|
||||||
|
imcLock.get().fdwInit &= ~INIT_GUIDMAP;
|
||||||
|
return imcLock.m_hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!imcLock.ClearCand())
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
// Populate conversion mode
|
||||||
|
if (!(imcLock.get().fdwInit & INIT_CONVERSION))
|
||||||
|
{
|
||||||
|
DWORD dwConv = (imcLock.get().fdwConversion & IME_CMODE_SOFTKBD);
|
||||||
|
if (LangID)
|
||||||
|
{
|
||||||
|
if (PRIMARYLANGID(LangID) == LANG_JAPANESE)
|
||||||
|
{
|
||||||
|
dwConv |= IME_CMODE_ROMAN | IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE;
|
||||||
|
}
|
||||||
|
else if (PRIMARYLANGID(LangID) != LANG_KOREAN)
|
||||||
|
{
|
||||||
|
dwConv |= IME_CMODE_NATIVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imcLock.get().fdwConversion |= dwConv;
|
||||||
|
imcLock.get().fdwInit |= INIT_CONVERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate sentence mode
|
||||||
|
imcLock.get().fdwSentence |= IME_SMODE_PHRASEPREDICT;
|
||||||
|
|
||||||
|
// Populate LOGFONT
|
||||||
|
if (!(imcLock.get().fdwInit & INIT_LOGFONT))
|
||||||
|
{
|
||||||
|
// Get logical font
|
||||||
|
LOGFONTW lf;
|
||||||
|
HDC hDC = ::GetDC(imcLock.get().hWnd);
|
||||||
|
HGDIOBJ hFont = GetCurrentObject(hDC, OBJ_FONT);
|
||||||
|
::GetObjectW(hFont, sizeof(LOGFONTW), &lf);
|
||||||
|
::ReleaseDC(imcLock.get().hWnd, hDC);
|
||||||
|
|
||||||
|
imcLock.get().lfFont.W = lf;
|
||||||
|
imcLock.get().fdwInit |= INIT_LOGFONT;
|
||||||
|
}
|
||||||
|
imcLock.get().lfFont.W.lfCharSet = GetCharsetFromLangId(LangID);
|
||||||
|
|
||||||
|
imcLock.InitContext();
|
||||||
|
|
||||||
|
return imcLock.m_hr;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Compartment
|
* Compartment
|
||||||
*/
|
*/
|
||||||
|
@ -1037,6 +1126,19 @@ public:
|
||||||
|
|
||||||
HRESULT CreateInputContext(TLS *pTLS, HIMC hIMC);
|
HRESULT CreateInputContext(TLS *pTLS, HIMC hIMC);
|
||||||
HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC);
|
HRESULT DestroyInputContext(TLS *pTLS, HIMC hIMC);
|
||||||
|
ITfContext *GetInputContext(CicIMCCLock<CTFIMECONTEXT>& imeContext);
|
||||||
|
|
||||||
|
HRESULT SelectEx(
|
||||||
|
TLS *pTLS,
|
||||||
|
ITfThreadMgr_P *pThreadMgr,
|
||||||
|
HIMC hIMC,
|
||||||
|
BOOL fSelect,
|
||||||
|
HKL hKL);
|
||||||
|
HRESULT OnSetOpenStatus(
|
||||||
|
TLS *pTLS,
|
||||||
|
ITfThreadMgr_P *pThreadMgr,
|
||||||
|
CicIMCLock& imcLock,
|
||||||
|
CicInputContext *pCicIC);
|
||||||
|
|
||||||
void PostTransMsg(HWND hWnd, INT cTransMsgs, LPTRANSMSG pTransMsgs);
|
void PostTransMsg(HWND hWnd, INT cTransMsgs, LPTRANSMSG pTransMsgs);
|
||||||
void GetDocumentManager(CicIMCCLock<CTFIMECONTEXT>& imeContext);
|
void GetDocumentManager(CicIMCCLock<CTFIMECONTEXT>& imeContext);
|
||||||
|
@ -1764,12 +1866,81 @@ HRESULT CicBridge::DestroyInputContext(TLS *pTLS, HIMC hIMC)
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ITfContext *
|
||||||
|
CicBridge::GetInputContext(CicIMCCLock<CTFIMECONTEXT>& imeContext)
|
||||||
|
{
|
||||||
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
|
if (!pCicIC)
|
||||||
|
return NULL;
|
||||||
|
return pCicIC->m_pContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @unimplemented
|
||||||
|
*/
|
||||||
|
HRESULT CicBridge::OnSetOpenStatus(
|
||||||
|
TLS *pTLS,
|
||||||
|
ITfThreadMgr_P *pThreadMgr,
|
||||||
|
CicIMCLock& imcLock,
|
||||||
|
CicInputContext *pCicIC)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
HRESULT
|
||||||
|
CicBridge::SelectEx(
|
||||||
|
TLS *pTLS,
|
||||||
|
ITfThreadMgr_P *pThreadMgr,
|
||||||
|
HIMC hIMC,
|
||||||
|
BOOL fSelect,
|
||||||
|
HKL hKL)
|
||||||
|
{
|
||||||
|
CicIMCLock imcLock(hIMC);
|
||||||
|
if (FAILED(imcLock.m_hr))
|
||||||
|
return imcLock.m_hr;
|
||||||
|
|
||||||
|
CicIMCCLock<CTFIMECONTEXT> imeContext(imcLock.get().hCtfImeContext);
|
||||||
|
if (!imeContext)
|
||||||
|
imeContext.m_hr = E_FAIL;
|
||||||
|
if (FAILED(imeContext.m_hr))
|
||||||
|
return imeContext.m_hr;
|
||||||
|
|
||||||
|
CicInputContext *pCicIC = imeContext.get().m_pCicIC;
|
||||||
|
if (pCicIC)
|
||||||
|
pCicIC->m_dw2[11] |= 1;
|
||||||
|
|
||||||
|
if (fSelect)
|
||||||
|
{
|
||||||
|
if (pCicIC)
|
||||||
|
pCicIC->m_dw2[1] &= ~1;
|
||||||
|
if (imcLock.get().fOpen)
|
||||||
|
OnSetOpenStatus(pTLS, pThreadMgr, imcLock, pCicIC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ITfContext *pContext = GetInputContext(imeContext);
|
||||||
|
pThreadMgr->RequestPostponedLock(pContext);
|
||||||
|
if (pCicIC)
|
||||||
|
pCicIC->m_dw2[11] &= ~1;
|
||||||
|
if (pContext)
|
||||||
|
pContext->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
return imeContext.m_hr;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct ENUM_CREATE_DESTROY_IC
|
typedef struct ENUM_CREATE_DESTROY_IC
|
||||||
{
|
{
|
||||||
TLS *m_pTLS;
|
TLS *m_pTLS;
|
||||||
CicBridge *m_pBridge;
|
CicBridge *m_pBridge;
|
||||||
} ENUM_CREATE_DESTROY_IC, *PENUM_CREATE_DESTROY_IC;
|
} ENUM_CREATE_DESTROY_IC, *PENUM_CREATE_DESTROY_IC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam)
|
BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam)
|
||||||
{
|
{
|
||||||
PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
|
PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
|
||||||
|
@ -1777,6 +1948,9 @@ BOOL CALLBACK CicBridge::EnumCreateInputContextCallback(HIMC hIMC, LPARAM lParam
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
BOOL CALLBACK CicBridge::EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam)
|
BOOL CALLBACK CicBridge::EnumDestroyInputContextCallback(HIMC hIMC, LPARAM lParam)
|
||||||
{
|
{
|
||||||
PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
|
PENUM_CREATE_DESTROY_IC pData = (PENUM_CREATE_DESTROY_IC)lParam;
|
||||||
|
@ -2454,14 +2628,29 @@ CtfImeInquireExW(
|
||||||
return Inquire(lpIMEInfo, lpszWndClass, dwSystemInfoFlags, hKL);
|
return Inquire(lpIMEInfo, lpszWndClass, dwSystemInfoFlags, hKL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* CtfImeSelectEx (MSCTFIME.@)
|
||||||
|
*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
EXTERN_C BOOL WINAPI
|
EXTERN_C BOOL WINAPI
|
||||||
CtfImeSelectEx(
|
CtfImeSelectEx(
|
||||||
_In_ HIMC hIMC,
|
_In_ HIMC hIMC,
|
||||||
_In_ BOOL fSelect,
|
_In_ BOOL fSelect,
|
||||||
_In_ HKL hKL)
|
_In_ HKL hKL)
|
||||||
{
|
{
|
||||||
FIXME("stub:(%p, %d, %p)\n", hIMC, fSelect, hKL);
|
TRACE("(%p, %d, %p)\n", hIMC, fSelect, hKL);
|
||||||
return FALSE;
|
|
||||||
|
TLS *pTLS = TLS::PeekTLS();
|
||||||
|
if (!pTLS)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
InternalSelectEx(hIMC, fSelect, LOWORD(hKL));
|
||||||
|
|
||||||
|
if (!pTLS->m_pBridge || !pTLS->m_pThreadMgr)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
return pTLS->m_pBridge->SelectEx(pTLS, pTLS->m_pThreadMgr, hIMC, fSelect, hKL);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN_C LRESULT WINAPI
|
EXTERN_C LRESULT WINAPI
|
||||||
|
|
|
@ -28,14 +28,6 @@
|
||||||
#include <cicero/cicimc.h>
|
#include <cicero/cicimc.h>
|
||||||
#include <cicero/cictf.h>
|
#include <cicero/cictf.h>
|
||||||
|
|
||||||
class CicInputContext;
|
|
||||||
|
|
||||||
typedef struct tagCTFIMECONTEXT
|
|
||||||
{
|
|
||||||
CicInputContext *m_pCicIC;
|
|
||||||
DWORD m_dwCicFlags;
|
|
||||||
} CTFIMECONTEXT, *PCTFIMECONTEXT;
|
|
||||||
|
|
||||||
#include <wine/debug.h>
|
#include <wine/debug.h>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
|
@ -7,11 +7,20 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// struct CTFIMECONTEXT;
|
||||||
// class CIC_IMCC_LOCK<T_DATA>;
|
// class CIC_IMCC_LOCK<T_DATA>;
|
||||||
// class CicIMCCLock<T_DATA>;
|
// class CicIMCCLock<T_DATA>;
|
||||||
// class CIC_IMC_LOCK;
|
// class CIC_IMC_LOCK;
|
||||||
// class CicIMCLock;
|
// class CicIMCLock;
|
||||||
|
|
||||||
|
class CicInputContext;
|
||||||
|
|
||||||
|
typedef struct tagCTFIMECONTEXT
|
||||||
|
{
|
||||||
|
CicInputContext *m_pCicIC;
|
||||||
|
DWORD m_dwCicFlags;
|
||||||
|
} CTFIMECONTEXT, *PCTFIMECONTEXT;
|
||||||
|
|
||||||
template <typename T_DATA>
|
template <typename T_DATA>
|
||||||
class CIC_IMCC_LOCK
|
class CIC_IMCC_LOCK
|
||||||
{
|
{
|
||||||
|
@ -143,6 +152,8 @@ public:
|
||||||
return imccLock.get().dwCompStrLen > 0;
|
return imccLock.get().dwCompStrLen > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL ClearCand();
|
||||||
|
|
||||||
BOOL UseVerticalCompWindow() const
|
BOOL UseVerticalCompWindow() const
|
||||||
{
|
{
|
||||||
return m_pIC->cfCompForm.dwStyle && ((m_pIC->lfFont.A.lfEscapement / 900) % 4 == 3);
|
return m_pIC->cfCompForm.dwStyle && ((m_pIC->lfFont.A.lfEscapement / 900) % 4 == 3);
|
||||||
|
@ -172,3 +183,51 @@ protected:
|
||||||
return ::ImmUnlockIMC(hIMC) ? S_OK : E_FAIL;
|
return ::ImmUnlockIMC(hIMC) ? S_OK : E_FAIL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline BOOL CicIMCLock::ClearCand()
|
||||||
|
{
|
||||||
|
HIMCC hNewCandInfo, hCandInfo = m_pIC->hCandInfo;
|
||||||
|
if (hCandInfo)
|
||||||
|
{
|
||||||
|
hNewCandInfo = ImmReSizeIMCC(hCandInfo, 1964);
|
||||||
|
if (!hNewCandInfo)
|
||||||
|
{
|
||||||
|
ImmDestroyIMCC(m_pIC->hCandInfo);
|
||||||
|
m_pIC->hCandInfo = ImmCreateIMCC(1964);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hNewCandInfo = ImmCreateIMCC(1964u);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pIC->hCandInfo = hNewCandInfo;
|
||||||
|
if (!m_pIC->hCandInfo)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
CicIMCCLock<CANDIDATEINFO> candInfo(m_pIC->hCandInfo);
|
||||||
|
if (!candInfo)
|
||||||
|
{
|
||||||
|
ImmDestroyIMCC(m_pIC->hCandInfo);
|
||||||
|
m_pIC->hCandInfo = ImmCreateIMCC(1964);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
candInfo.get().dwSize = 1964;
|
||||||
|
candInfo.get().dwCount = 0;
|
||||||
|
candInfo.get().dwOffset[0] = sizeof(CANDIDATEINFO);
|
||||||
|
|
||||||
|
LPBYTE pb = (LPBYTE)(&candInfo.get());
|
||||||
|
pb += sizeof(CANDIDATEINFO);
|
||||||
|
|
||||||
|
LPDWORD pdwUnknown = (LPDWORD)pb;
|
||||||
|
pdwUnknown[0] = candInfo.get().dwSize - sizeof(CANDIDATEINFO); // +0x0
|
||||||
|
pdwUnknown[2] = 0; // +0x08
|
||||||
|
pdwUnknown[3] = 0; // +0x0c
|
||||||
|
pdwUnknown[4] = 0; // +0x10
|
||||||
|
pdwUnknown[1] = 1; // +0x04
|
||||||
|
pdwUnknown[5] = 9; // +0x14
|
||||||
|
pdwUnknown[6] = 1048; // +0x18
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue