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.
803 lines
26 KiB
803 lines
26 KiB
/*++
|
|
|
|
Copyright (c) 2001, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
editcomp.cpp
|
|
|
|
Abstract:
|
|
|
|
This file implements the EditCompositionString Class.
|
|
|
|
Author:
|
|
|
|
Revision History:
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
|
|
#include "private.h"
|
|
#include "editcomp.h"
|
|
#include "context.h"
|
|
#include "compstr.h"
|
|
#include "profile.h"
|
|
#include "delay.h"
|
|
|
|
// static BOOL fHanjaRequested = FALSE; // consider: this is not thread safe
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// EditCompositionString
|
|
|
|
//
|
|
// Set (almost) all in composition string
|
|
//
|
|
|
|
HRESULT
|
|
EditCompositionString::SetString(
|
|
IMCLock& imc,
|
|
CicInputContext& CicContext,
|
|
CWCompString* CompStr,
|
|
CWCompAttribute* CompAttr,
|
|
CWCompClause* CompClause,
|
|
CWCompCursorPos* CompCursorPos,
|
|
CWCompDeltaStart* CompDeltaStart,
|
|
CWCompTfGuidAtom* CompGuid,
|
|
OUT BOOL* lpbBufferOverflow,
|
|
CWCompString* CompReadStr,
|
|
CWCompAttribute* CompReadAttr,
|
|
CWCompClause* CompReadClause,
|
|
CWCompString* ResultStr,
|
|
CWCompClause* ResultClause,
|
|
CWCompString* ResultReadStr,
|
|
CWCompClause* ResultReadClause,
|
|
CWInterimString* InterimStr
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
#ifdef UNSELECTCHECK
|
|
if (!_pAImeContext->m_fSelected)
|
|
return S_OK;
|
|
#endif UNSELECTCHECK
|
|
|
|
#if 0
|
|
DWORD dwImeCompatFlags = ImmGetAppCompatFlags((HIMC)imc);
|
|
#endif
|
|
|
|
if (CicContext.m_fHanjaReConversion.IsSetFlag() ||
|
|
CicContext.m_fInClearDocFeedEditSession.IsSetFlag())
|
|
{
|
|
#if 0
|
|
if ((dwImeCompatFlags & IMECOMPAT_AIMM_TRIDENT55) && CicContext.m_fHanjaReConversion.IsSetFlag())
|
|
CicContext.m_fHanjaRequested.SetFlag();
|
|
#endif
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// Clear the contents of candidate list
|
|
//
|
|
imc.ClearCand();
|
|
|
|
TRANSMSG msg;
|
|
if (InterimStr) {
|
|
hr = _MakeInterimData(imc,
|
|
InterimStr,
|
|
&msg.lParam);
|
|
}
|
|
else {
|
|
hr = _MakeCompositionData(imc,
|
|
CompStr, CompAttr, CompClause,
|
|
CompCursorPos, CompDeltaStart,
|
|
CompGuid,
|
|
CompReadStr, CompReadAttr, CompReadClause,
|
|
ResultStr, ResultClause,
|
|
ResultReadStr, ResultReadClause,
|
|
&msg.lParam,
|
|
lpbBufferOverflow);
|
|
}
|
|
if ( hr == S_OK || // In case of valid dwCompSize in the CCompStrFactory::CreateCompositionString
|
|
(hr == S_FALSE && CicContext.m_fStartComposition.IsSetFlag())
|
|
// In case of empty dwCompSize but still m_fStartComposition
|
|
) {
|
|
//
|
|
// Is available compstr/attr/clause, compread, result or resultread ?
|
|
//
|
|
bool fNoCompResultData = false;
|
|
if (! (msg.lParam & (GCS_COMP | GCS_COMPREAD | GCS_RESULT | GCS_RESULTREAD))) {
|
|
DebugMsg(TF_GENERAL, TEXT("EditCompositionString::SetString: No data in compstr, compread, result or resultread."));
|
|
fNoCompResultData = true;
|
|
if (CicContext.m_fStartComposition.IsResetFlag()) {
|
|
DebugMsg(TF_ERROR, TEXT("EditCompositionString::SetString: No send WM_IME_STARTCOMPOSITION yet."));
|
|
return S_FALSE;
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
//
|
|
// New Trident(5.5 & 6.0) had a bug to convert Hanja.
|
|
// So _GenerateHanja() funtion try to generate message like as Korean
|
|
// legacy IME behavior.
|
|
//
|
|
// Send WM_IME_ENDCOMPOSITION and then WM_IME_COMPOSITION GCS_RESULT msg.
|
|
//
|
|
if ((dwImeCompatFlags & IMECOMPAT_AIMM_TRIDENT55) && CicContext.m_fHanjaRequested.IsSetFlag() &&
|
|
!fNoCompResultData && (msg.lParam & GCS_RESULT))
|
|
{
|
|
LANGID langid = LANG_NEUTRAL;
|
|
|
|
//
|
|
// TLS doesn't inherit in edit session.
|
|
//
|
|
TLS* ptls = TLS::GetTLS();
|
|
if (ptls != NULL)
|
|
{
|
|
CicProfile* _pProfile = ptls->GetCicProfile();
|
|
if (_pProfile != NULL)
|
|
{
|
|
_pProfile->GetLangId(&langid);
|
|
}
|
|
}
|
|
|
|
CicContext.m_fHanjaRequested.ResetFlag();
|
|
|
|
if (PRIMARYLANGID(langid) == LANG_KOREAN)
|
|
{
|
|
return _GenerateKoreanComposition(imc, CicContext, ResultStr);
|
|
}
|
|
}
|
|
|
|
CicContext.m_fHanjaRequested.ResetFlag();
|
|
#else
|
|
LANGID langid = LANG_NEUTRAL;
|
|
|
|
//
|
|
// TLS doesn't inherit in edit session.
|
|
//
|
|
TLS* ptls = TLS::GetTLS();
|
|
if (ptls != NULL)
|
|
{
|
|
CicProfile* _pProfile = ptls->GetCicProfile();
|
|
if (_pProfile != NULL)
|
|
{
|
|
_pProfile->GetLangId(&langid);
|
|
}
|
|
}
|
|
|
|
if (PRIMARYLANGID(langid) == LANG_KOREAN &&
|
|
!fNoCompResultData && (msg.lParam & GCS_RESULT))
|
|
{
|
|
if (_GenerateKoreanComposition(imc, CicContext, ResultStr) == S_OK)
|
|
{
|
|
return S_OK;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// set private input context
|
|
//
|
|
bool fSetStartComp = false;
|
|
|
|
if (CicContext.m_fStartComposition.IsResetFlag()) {
|
|
CicContext.m_fStartComposition.SetFlag();
|
|
TRANSMSG start_msg;
|
|
start_msg.message = WM_IME_STARTCOMPOSITION;
|
|
start_msg.wParam = (WPARAM) 0;
|
|
start_msg.lParam = (LPARAM) 0;
|
|
if (CicContext.m_pMessageBuffer) {
|
|
CicContext.m_pMessageBuffer->SetData(start_msg);
|
|
fSetStartComp = true;
|
|
}
|
|
}
|
|
|
|
if (! fNoCompResultData) {
|
|
msg.message = WM_IME_COMPOSITION;
|
|
|
|
IMCCLock<COMPOSITIONSTRING> pCompStr((HIMCC)imc->hCompStr);
|
|
|
|
if (msg.lParam & GCS_RESULT)
|
|
{
|
|
msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwResultStrOffset));
|
|
|
|
if (PRIMARYLANGID(langid) == LANG_KOREAN &&
|
|
msg.lParam & GCS_RESULTSTR)
|
|
{
|
|
TRANSMSG comp_result_msg;
|
|
|
|
comp_result_msg.message = msg.message;
|
|
comp_result_msg.wParam = msg.wParam;
|
|
comp_result_msg.lParam = GCS_RESULTSTR;
|
|
|
|
//
|
|
// Only set GCS_RESULTSTR for compatibility(#487046).
|
|
//
|
|
if (CicContext.m_pMessageBuffer)
|
|
CicContext.m_pMessageBuffer->SetData(comp_result_msg);
|
|
|
|
msg.lParam &= ~GCS_RESULTSTR;
|
|
|
|
//
|
|
// Send another composition string message.
|
|
//
|
|
if (msg.lParam & GCS_COMPSTR)
|
|
msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwCompStrOffset));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwCompStrOffset));
|
|
}
|
|
|
|
if (CicContext.m_pMessageBuffer) {
|
|
CicContext.m_pMessageBuffer->SetData(msg);
|
|
|
|
//
|
|
// Internal notification to UI window
|
|
// When receive this msg in UI wnd, then calls QueryCharPos().
|
|
//
|
|
if (fSetStartComp) {
|
|
TRANSMSG notify_msg;
|
|
notify_msg.message = WM_IME_NOTIFY;
|
|
notify_msg.wParam = (WPARAM)WM_IME_STARTCOMPOSITION;
|
|
notify_msg.lParam = 0;
|
|
CicContext.m_pMessageBuffer->SetData(notify_msg);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
msg.message = WM_IME_COMPOSITION;
|
|
if ((PRIMARYLANGID(langid) != LANG_JAPANESE))
|
|
{
|
|
msg.wParam = (WPARAM)VK_ESCAPE;
|
|
msg.lParam = (LPARAM)(GCS_COMPREAD | GCS_COMP | GCS_CURSORPOS | GCS_DELTASTART);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// #509247
|
|
//
|
|
// Some apps don't accept lParam without compstr in hIMC.
|
|
//
|
|
msg.wParam = 0;
|
|
msg.lParam = 0;
|
|
}
|
|
|
|
if (CicContext.m_pMessageBuffer)
|
|
CicContext.m_pMessageBuffer->SetData(msg);
|
|
}
|
|
|
|
if ((ResultStr && ResultStr->GetSize() && !(msg.lParam & GCS_COMP))
|
|
|| fNoCompResultData) {
|
|
//
|
|
// We're ending the composition
|
|
//
|
|
CicContext.m_fStartComposition.ResetFlag();
|
|
TRANSMSG end_msg;
|
|
end_msg.message = WM_IME_ENDCOMPOSITION;
|
|
end_msg.wParam = (WPARAM) 0;
|
|
end_msg.lParam = (LPARAM) 0;
|
|
if (CicContext.m_pMessageBuffer) {
|
|
CicContext.m_pMessageBuffer->SetData(end_msg);
|
|
|
|
//
|
|
// Internal notification to UI window
|
|
// When receive this msg in UI wnd, then clear QueryCharPos's flag.
|
|
//
|
|
TRANSMSG notify_msg;
|
|
notify_msg.message = WM_IME_NOTIFY;
|
|
notify_msg.wParam = (WPARAM)WM_IME_ENDCOMPOSITION;
|
|
notify_msg.lParam = 0;
|
|
CicContext.m_pMessageBuffer->SetData(notify_msg);
|
|
|
|
if (CicContext.m_fInProcessKey.IsSetFlag())
|
|
CicContext.m_fGeneratedEndComposition.SetFlag();
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
|
|
#endif
|
|
|
|
#if 0
|
|
// Move to editses.cpp
|
|
if (fGenerateMessage) {
|
|
CicContext.GenerateMessage(imc);
|
|
}
|
|
#endif
|
|
hr = S_OK;
|
|
|
|
//
|
|
// Update the previous result string cache.
|
|
//
|
|
CicContext.UpdatePrevResultStr(imc);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// Make composition string data in the IMCCLock<_COMPOSITIONSTRING> comp.
|
|
//
|
|
|
|
HRESULT
|
|
EditCompositionString::_MakeCompositionData(
|
|
IMCLock& imc,
|
|
CWCompString* CompStr,
|
|
CWCompAttribute* CompAttr,
|
|
CWCompClause* CompClause,
|
|
CWCompCursorPos* CompCursorPos,
|
|
CWCompDeltaStart* CompDeltaStart,
|
|
CWCompTfGuidAtom* CompGuid,
|
|
CWCompString* CompReadStr,
|
|
CWCompAttribute* CompReadAttr,
|
|
CWCompClause* CompReadClause,
|
|
CWCompString* ResultStr,
|
|
CWCompClause* ResultClause,
|
|
CWCompString* ResultReadStr,
|
|
CWCompClause* ResultReadClause,
|
|
OUT LPARAM* lpdwFlag,
|
|
OUT BOOL* lpbBufferOverflow
|
|
)
|
|
{
|
|
DebugMsg(TF_FUNC, TEXT("EditCompositionString::MakeCompositionData"));
|
|
|
|
*lpdwFlag = (LPARAM) 0;
|
|
|
|
HRESULT hr;
|
|
|
|
CCompStrFactory compstrfactory(imc->hCompStr);
|
|
if (FAILED(hr=compstrfactory.GetResult()))
|
|
return hr;
|
|
|
|
hr = compstrfactory.CreateCompositionString(CompStr,
|
|
CompAttr,
|
|
CompClause,
|
|
CompGuid,
|
|
CompReadStr,
|
|
CompReadAttr,
|
|
CompReadClause,
|
|
ResultStr,
|
|
ResultClause,
|
|
ResultReadStr,
|
|
ResultReadClause
|
|
);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
//
|
|
// Composition string
|
|
//
|
|
if (lpbBufferOverflow != NULL)
|
|
*lpbBufferOverflow = FALSE;
|
|
|
|
if (CompStr && CompStr->GetSize()) {
|
|
#if 0
|
|
/*
|
|
* If composition string length over the buffer of COMPOSITIONSTRING.compstr[NMAXKEY],
|
|
* then we want to finalize this composition string.
|
|
*/
|
|
if ((*comp)->dwCompStrLen >= NMAXKEY) {
|
|
if (lpbBufferOverflow != NULL)
|
|
*lpbBufferOverflow = TRUE;
|
|
//
|
|
// Clear compsition string length.
|
|
//
|
|
(*comp)->dwCompStrLen = 0;
|
|
//
|
|
// Make result string.
|
|
//
|
|
(*comp)->dwResultStrLen = NMAXKEY;
|
|
CompStr->ReadCompData((*comp)->W.resultstr, ARRAYSIZE((*comp)->W.resultstr));
|
|
*lpdwFlag |= (LPARAM) GCS_RESULTSTR;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
hr = compstrfactory.WriteData<CWCompString, WCHAR>(*CompStr,
|
|
&compstrfactory->dwCompStrLen,
|
|
&compstrfactory->dwCompStrOffset
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_COMPSTR;
|
|
else
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if ((lpbBufferOverflow == NULL) ||
|
|
(lpbBufferOverflow != NULL && (! *lpbBufferOverflow))) {
|
|
|
|
//
|
|
// Compoition attribute
|
|
//
|
|
if (CompAttr && CompAttr->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompAttribute, BYTE>(*CompAttr,
|
|
&compstrfactory->dwCompAttrLen,
|
|
&compstrfactory->dwCompAttrOffset
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_COMPATTR;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Compoition clause
|
|
//
|
|
if (CompClause && CompClause->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompClause, DWORD>(*CompClause,
|
|
&compstrfactory->dwCompClauseLen,
|
|
&compstrfactory->dwCompClauseOffset
|
|
);
|
|
compstrfactory->dwCompClauseLen *= sizeof(DWORD);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_COMPCLAUSE;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Composition Reading string
|
|
//
|
|
if (CompReadStr && CompReadStr->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompString, WCHAR>(*CompReadStr,
|
|
&compstrfactory->dwCompReadStrLen,
|
|
&compstrfactory->dwCompReadStrOffset
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_COMPREADSTR;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Compoition Reading attribute
|
|
//
|
|
if (CompReadAttr && CompReadAttr->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompAttribute, BYTE>(*CompReadAttr,
|
|
&compstrfactory->dwCompReadAttrLen,
|
|
&compstrfactory->dwCompReadAttrOffset
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_COMPREADATTR;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Composition Reading clause
|
|
//
|
|
if (CompReadClause && CompReadClause->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompClause, DWORD>(*CompReadClause,
|
|
&compstrfactory->dwCompReadClauseLen,
|
|
&compstrfactory->dwCompReadClauseOffset
|
|
);
|
|
compstrfactory->dwCompReadClauseLen *= sizeof(DWORD);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_COMPREADCLAUSE;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Result String
|
|
//
|
|
if (ResultStr && ResultStr->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompString, WCHAR>(*ResultStr,
|
|
&compstrfactory->dwResultStrLen,
|
|
&compstrfactory->dwResultStrOffset
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_RESULTSTR;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Result clause
|
|
//
|
|
if (ResultClause && ResultClause->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompClause, DWORD>(*ResultClause,
|
|
&compstrfactory->dwResultClauseLen,
|
|
&compstrfactory->dwResultClauseOffset
|
|
);
|
|
compstrfactory->dwResultClauseLen *= sizeof(DWORD);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_RESULTCLAUSE;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Result Reading string
|
|
//
|
|
if (ResultReadStr && ResultReadStr->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompString, WCHAR>(*ResultReadStr,
|
|
&compstrfactory->dwResultReadStrLen,
|
|
&compstrfactory->dwResultReadStrOffset
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_RESULTREADSTR;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Result Reading clause
|
|
//
|
|
if (ResultReadClause && ResultReadClause->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWCompClause, DWORD>(*ResultReadClause,
|
|
&compstrfactory->dwResultReadClauseLen,
|
|
&compstrfactory->dwResultReadClauseOffset
|
|
);
|
|
compstrfactory->dwResultReadClauseLen *= sizeof(DWORD);
|
|
if (SUCCEEDED(hr))
|
|
*lpdwFlag |= (LPARAM) GCS_RESULTREADCLAUSE;
|
|
else
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// TfGuidAtom
|
|
//
|
|
if (CompGuid && CompGuid->GetSize()) {
|
|
hr = compstrfactory.MakeGuidMapAttribute(CompGuid, CompAttr);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// set INIT_GUID_ATOM flag in the fdwInit.
|
|
imc->fdwInit |= INIT_GUID_ATOM;
|
|
}
|
|
else
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Composition Cursor Position
|
|
//
|
|
if (CompCursorPos && CompCursorPos->GetSize()) {
|
|
CompCursorPos->ReadCompData(&compstrfactory->dwCursorPos, 1);
|
|
*lpdwFlag |= (LPARAM) GCS_CURSORPOS;
|
|
}
|
|
|
|
//
|
|
// Delta Start
|
|
//
|
|
if (CompDeltaStart && CompDeltaStart->GetSize()) {
|
|
CompDeltaStart->ReadCompData(&compstrfactory->dwDeltaStart, 1);
|
|
*lpdwFlag |= (LPARAM) GCS_DELTASTART;
|
|
}
|
|
|
|
Exit:
|
|
//
|
|
// Copy back hCompStr to the Input Context
|
|
//
|
|
imc->hCompStr = compstrfactory.GetHandle();
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Make interim string data in the IMCCLock<_COMPOSITIONSTRING> comp.
|
|
//
|
|
|
|
HRESULT
|
|
EditCompositionString::_MakeInterimData(
|
|
IMCLock& imc,
|
|
CWInterimString* InterimStr,
|
|
LPARAM* lpdwFlag
|
|
)
|
|
{
|
|
DebugMsg(TF_FUNC, TEXT("EditCompositionString::MakeInterimData"));
|
|
|
|
*lpdwFlag = (LPARAM) 0;
|
|
|
|
//
|
|
// Interim character and result string
|
|
//
|
|
|
|
HRESULT hr;
|
|
|
|
CCompStrFactory compstrfactory(imc->hCompStr);
|
|
if (FAILED(hr=compstrfactory.GetResult()))
|
|
return hr;
|
|
|
|
hr = compstrfactory.CreateCompositionString(InterimStr);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
//
|
|
// Result string
|
|
//
|
|
if (InterimStr && InterimStr->GetSize()) {
|
|
hr = compstrfactory.WriteData<CWInterimString, WCHAR>(*InterimStr,
|
|
&compstrfactory->dwResultStrLen,
|
|
&compstrfactory->dwResultStrOffset
|
|
);
|
|
*lpdwFlag |= (LPARAM) GCS_RESULTSTR;
|
|
}
|
|
|
|
//
|
|
// Composition string (Interim character)
|
|
// Compoition attribute
|
|
//
|
|
CWCompString ch;
|
|
CWCompAttribute attr;
|
|
InterimStr->ReadInterimChar(&ch, &attr);
|
|
if (ch.GetSize() && ch.GetAt(0)) {
|
|
hr = compstrfactory.WriteData<CWCompString, WCHAR>(ch,
|
|
&compstrfactory->dwCompStrLen,
|
|
&compstrfactory->dwCompStrOffset
|
|
);
|
|
*lpdwFlag |= (LPARAM) GCS_COMPSTR;
|
|
|
|
hr = compstrfactory.WriteData<CWCompAttribute, BYTE>(attr,
|
|
&compstrfactory->dwCompAttrLen,
|
|
&compstrfactory->dwCompAttrOffset
|
|
);
|
|
*lpdwFlag |= (LPARAM) GCS_COMPATTR;
|
|
|
|
*lpdwFlag |= (LPARAM) CS_INSERTCHAR | CS_NOMOVECARET;
|
|
}
|
|
|
|
//
|
|
// Copy back hCompStr to the Input Context
|
|
//
|
|
imc->hCompStr = compstrfactory.GetHandle();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//
|
|
// Generate WM_IME_ENDCOMPOSITION and WM_IME_COMPOSITION message for
|
|
// Trident 5.5 version. Since Trident 5.5 always expect WM_IME_ENDCOMPOSITION
|
|
// first in case of Hanja conversion.
|
|
//
|
|
|
|
HRESULT
|
|
EditCompositionString::_GenerateKoreanComposition(
|
|
IMCLock& imc,
|
|
CicInputContext& CicContext,
|
|
CWCompString* ResultStr)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
DWORD dwImeCompatFlags = ImmGetAppCompatFlags(NULL);
|
|
BOOL fEndCompFirst = FALSE;
|
|
|
|
if (!MsimtfIsWindowFiltered(::GetFocus()) ||
|
|
(dwImeCompatFlags & IMECOMPAT_AIMM12_TRIDENT))
|
|
{
|
|
fEndCompFirst = TRUE;
|
|
}
|
|
|
|
if (ResultStr && ResultStr->GetSize())
|
|
{
|
|
if (fEndCompFirst)
|
|
{
|
|
//
|
|
// We're ending the composition
|
|
//
|
|
CicContext.m_fStartComposition.ResetFlag();
|
|
|
|
TRANSMSG end_msg;
|
|
end_msg.message = WM_IME_ENDCOMPOSITION;
|
|
end_msg.wParam = (WPARAM) 0;
|
|
end_msg.lParam = (LPARAM) 0;
|
|
|
|
if (CicContext.m_pMessageBuffer)
|
|
{
|
|
CicContext.m_pMessageBuffer->SetData(end_msg);
|
|
|
|
//
|
|
// Internal notification to UI window
|
|
// When receive this msg in UI wnd, then clear QueryCharPos's flag.
|
|
//
|
|
TRANSMSG notify_msg;
|
|
|
|
notify_msg.message = WM_IME_NOTIFY;
|
|
notify_msg.wParam = (WPARAM)WM_IME_ENDCOMPOSITION;
|
|
notify_msg.lParam = 0;
|
|
CicContext.m_pMessageBuffer->SetData(notify_msg);
|
|
|
|
if (CicContext.m_fInProcessKey.IsSetFlag())
|
|
CicContext.m_fGeneratedEndComposition.SetFlag();
|
|
}
|
|
|
|
TRANSMSG result_msg;
|
|
result_msg.message = WM_IME_COMPOSITION;
|
|
result_msg.lParam = GCS_RESULTSTR;
|
|
|
|
IMCCLock<COMPOSITIONSTRING> pCompStr((HIMCC)imc->hCompStr);
|
|
|
|
result_msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwResultStrOffset));
|
|
|
|
if (CicContext.m_pMessageBuffer)
|
|
{
|
|
CicContext.m_pMessageBuffer->SetData(result_msg);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Windows Bug 716419
|
|
// This is the same behavior with WinXP RTM AIMM1.2 code.
|
|
//
|
|
if (CicContext.m_fStartComposition.IsResetFlag()) {
|
|
CicContext.m_fStartComposition.SetFlag();
|
|
TRANSMSG start_msg;
|
|
start_msg.message = WM_IME_STARTCOMPOSITION;
|
|
start_msg.wParam = (WPARAM) 0;
|
|
start_msg.lParam = (LPARAM) 0;
|
|
if (CicContext.m_pMessageBuffer) {
|
|
CicContext.m_pMessageBuffer->SetData(start_msg);
|
|
}
|
|
}
|
|
|
|
TRANSMSG result_msg;
|
|
result_msg.message = WM_IME_COMPOSITION;
|
|
result_msg.lParam = GCS_RESULTSTR;
|
|
|
|
IMCCLock<COMPOSITIONSTRING> pCompStr((HIMCC)imc->hCompStr);
|
|
|
|
result_msg.wParam = (WPARAM)(*(WCHAR*)pCompStr.GetOffsetPointer(pCompStr->dwResultStrOffset));
|
|
|
|
if (CicContext.m_pMessageBuffer)
|
|
{
|
|
CicContext.m_pMessageBuffer->SetData(result_msg);
|
|
}
|
|
|
|
//
|
|
// We're ending the composition
|
|
//
|
|
CicContext.m_fStartComposition.ResetFlag();
|
|
|
|
TRANSMSG end_msg;
|
|
end_msg.message = WM_IME_ENDCOMPOSITION;
|
|
end_msg.wParam = (WPARAM) 0;
|
|
end_msg.lParam = (LPARAM) 0;
|
|
|
|
if (CicContext.m_pMessageBuffer)
|
|
{
|
|
CicContext.m_pMessageBuffer->SetData(end_msg);
|
|
|
|
//
|
|
// Internal notification to UI window
|
|
// When receive this msg in UI wnd, then clear QueryCharPos's flag.
|
|
//
|
|
TRANSMSG notify_msg;
|
|
|
|
notify_msg.message = WM_IME_NOTIFY;
|
|
notify_msg.wParam = (WPARAM)WM_IME_ENDCOMPOSITION;
|
|
notify_msg.lParam = 0;
|
|
CicContext.m_pMessageBuffer->SetData(notify_msg);
|
|
|
|
if (CicContext.m_fInProcessKey.IsSetFlag())
|
|
CicContext.m_fGeneratedEndComposition.SetFlag();
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
IMCCLock<COMPOSITIONSTRING> comp(imc->hCompStr);
|
|
#endif
|
|
|
|
#if 0
|
|
// Move to editses.cpp
|
|
if (fGenerateMessage)
|
|
{
|
|
imc.GenerateMessage();
|
|
}
|
|
#endif
|
|
|
|
return hr;
|
|
}
|