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.
375 lines
10 KiB
375 lines
10 KiB
/*++
|
|
|
|
Copyright (c) 1985 - 1999, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
icocb.cpp
|
|
|
|
Abstract:
|
|
|
|
This file implements the CInputContextOwnerCallBack Class.
|
|
|
|
Author:
|
|
|
|
Revision History:
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
|
|
#include "private.h"
|
|
|
|
#include "icocb.h"
|
|
#include "cime.h"
|
|
#include "imeapp.h"
|
|
#include "mouse.h"
|
|
#include "tsattrs.h"
|
|
#include "imtls.h"
|
|
#include "a_context.h"
|
|
#include "candpos.h"
|
|
|
|
|
|
CInputContextOwnerCallBack::CInputContextOwnerCallBack(LIBTHREAD *pLibTLS
|
|
) : CInputContextOwner(ICOwnerSinkCallback, NULL)
|
|
{
|
|
m_pMouseSink = NULL;
|
|
|
|
m_pLibTLS = pLibTLS;
|
|
}
|
|
|
|
CInputContextOwnerCallBack::~CInputContextOwnerCallBack(
|
|
)
|
|
{
|
|
if (m_pMouseSink) {
|
|
m_pMouseSink->InternalRelease();
|
|
m_pMouseSink = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL CInputContextOwnerCallBack::Init()
|
|
{
|
|
//
|
|
// Create Mouse Sink
|
|
//
|
|
Assert(!m_pMouseSink);
|
|
|
|
m_pMouseSink = new CMouseSink;
|
|
if (m_pMouseSink == NULL)
|
|
return FALSE;
|
|
|
|
if (!m_pMouseSink->Init())
|
|
{
|
|
delete m_pMouseSink;
|
|
m_pMouseSink = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// static
|
|
HRESULT
|
|
CInputContextOwnerCallBack::ICOwnerSinkCallback(
|
|
UINT uCode,
|
|
ICOARGS *pargs,
|
|
void *pv
|
|
)
|
|
{
|
|
DebugMsg(TF_FUNC, "ICOwnerSinkCallback");
|
|
|
|
POINT pt;
|
|
IMTLS *ptls;
|
|
|
|
CInputContextOwnerCallBack* _this = (CInputContextOwnerCallBack*)pv;
|
|
|
|
switch (uCode)
|
|
{
|
|
case ICO_POINT_TO_ACP:
|
|
Assert(0);
|
|
return E_NOTIMPL;
|
|
|
|
case ICO_KEYDOWN:
|
|
case ICO_KEYUP:
|
|
*pargs->key.pfEaten = FALSE;
|
|
break;
|
|
|
|
case ICO_SCREENEXT:
|
|
{
|
|
ptls = IMTLS_GetOrAlloc();
|
|
if (ptls == NULL)
|
|
break;
|
|
IMCLock imc(ptls->hIMC);
|
|
if (imc.Invalid())
|
|
break;
|
|
|
|
GetClientRect(imc->hWnd, pargs->scr_ext.prc);
|
|
pt.x = pt.y = 0;
|
|
ClientToScreen(imc->hWnd, &pt);
|
|
|
|
pargs->scr_ext.prc->left += pt.x;
|
|
pargs->scr_ext.prc->right += pt.x;
|
|
pargs->scr_ext.prc->top += pt.y;
|
|
pargs->scr_ext.prc->bottom += pt.y;
|
|
}
|
|
|
|
break;
|
|
|
|
case ICO_TEXTEXT:
|
|
//
|
|
// consider.
|
|
//
|
|
// hack TextExtent from CANDIDATEFORM of HIMC.
|
|
//
|
|
// more hacks
|
|
// - may want to send WM_OPENCANDIDATEPOS to let apps
|
|
// call ImmSetCandidateWindow().
|
|
// - may need to calculate the actual point from rcArea.
|
|
//
|
|
{
|
|
CCandidatePosition cand_pos;
|
|
cand_pos.GetCandidatePosition(pargs->text_ext.prc);
|
|
}
|
|
break;
|
|
|
|
case ICO_STATUS:
|
|
pargs->status.pdcs->dwDynamicFlags = 0;
|
|
pargs->status.pdcs->dwStaticFlags = TF_SS_TRANSITORY;
|
|
break;
|
|
|
|
case ICO_WND:
|
|
{
|
|
ptls = IMTLS_GetOrAlloc();
|
|
if (ptls == NULL)
|
|
break;
|
|
IMCLock imc(ptls->hIMC);
|
|
*(pargs->hwnd.phwnd) = NULL;
|
|
if (imc.Invalid())
|
|
break;
|
|
|
|
*(pargs->hwnd.phwnd) = imc->hWnd;
|
|
}
|
|
break;
|
|
|
|
case ICO_ATTR:
|
|
return _this->GetAttribute(pargs->sys_attr.pguid, pargs->sys_attr.pvar);
|
|
|
|
case ICO_ADVISEMOUSE:
|
|
{
|
|
ptls = IMTLS_GetOrAlloc();
|
|
if (ptls == NULL)
|
|
break;
|
|
_this->m_pMouseSink->InternalAddRef();
|
|
return _this->m_pMouseSink->AdviseMouseSink(ptls->hIMC,
|
|
pargs->advise_mouse.rangeACP,
|
|
pargs->advise_mouse.pSink,
|
|
pargs->advise_mouse.pdwCookie);
|
|
}
|
|
break;
|
|
|
|
case ICO_UNADVISEMOUSE:
|
|
{
|
|
HRESULT hr = _this->m_pMouseSink->UnadviseMouseSink(pargs->unadvise_mouse.dwCookie);
|
|
_this->m_pMouseSink->InternalRelease();
|
|
return hr;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Assert(0); // shouldn't ever get here
|
|
break;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/*++
|
|
|
|
Method:
|
|
|
|
CInputContextOwnerCallBack::GetAttribute
|
|
|
|
Routine Description:
|
|
|
|
Implementation of ITfContextOwner::GetAttribute. Returns the value of a cicero
|
|
app property attribute.
|
|
|
|
Arguments:
|
|
|
|
|
|
pguid - [in] GUID of the attrib in question.
|
|
pvarValue - [out] VARIANT, receives the value. VT_EMPTY if we don't support it.
|
|
|
|
Return Value:
|
|
|
|
Returns S_OK if successful, or an error code otherwise.
|
|
|
|
--*/
|
|
|
|
HRESULT
|
|
CInputContextOwnerCallBack::GetAttribute(
|
|
const GUID *pguid,
|
|
VARIANT *pvarValue
|
|
)
|
|
{
|
|
TfGuidAtom ga;
|
|
const GUID *pguidValue;
|
|
IMTLS *ptls;
|
|
|
|
QuickVariantInit(pvarValue);
|
|
|
|
ptls = IMTLS_GetOrAlloc();
|
|
if (ptls == NULL)
|
|
return E_FAIL;
|
|
|
|
if (IsEqualGUID(*pguid, GUID_PROP_MODEBIAS))
|
|
{
|
|
// xlate conversion mode, sentence mode to cicero mode bias
|
|
IMCLock imc(ptls->hIMC);
|
|
if (imc.Invalid())
|
|
return E_FAIL;
|
|
|
|
CAImeContext* _pAImeContext = imc->m_pAImeContext;
|
|
ASSERT(_pAImeContext != NULL);
|
|
if (_pAImeContext == NULL)
|
|
return E_FAIL;
|
|
|
|
if (_pAImeContext->lModeBias == MODEBIASMODE_FILENAME)
|
|
{
|
|
pguidValue = &GUID_MODEBIAS_FILENAME;
|
|
}
|
|
else if (_pAImeContext->lModeBias == MODEBIASMODE_DIGIT)
|
|
{
|
|
pguidValue = &GUID_MODEBIAS_NUMERIC;
|
|
}
|
|
else
|
|
{
|
|
if (imc->fdwConversion & IME_CMODE_GUID_NULL) {
|
|
//
|
|
// If extended conversion mode were set on,
|
|
// returns GUID_NULL.
|
|
// No returns any MODEBIAS.
|
|
//
|
|
pguidValue = &GUID_NULL;
|
|
}
|
|
else
|
|
|
|
//
|
|
// existing logic:
|
|
//
|
|
// if imcp->lModeBias == MODEBIASMODE_DEFAULT
|
|
// IME_SMODE_CONVERSATION -> GUID_MODEBIAS_CONVERSATION
|
|
// otherwise -> GUID_MODEBIAS_NONE
|
|
// otherwise
|
|
// -> MODEBIASMODE_FILENAME -> GUID_MODEBIAS_FILENAME
|
|
//
|
|
|
|
if (_pAImeContext->lModeBias == MODEBIASMODE_DEFAULT)
|
|
{
|
|
pguidValue = &GUID_MODEBIAS_NONE;
|
|
|
|
if (imc->fdwConversion & IME_CMODE_KATAKANA)
|
|
{
|
|
if (imc->fdwConversion & IME_CMODE_FULLSHAPE)
|
|
pguidValue = &GUID_MODEBIAS_KATAKANA;
|
|
else
|
|
pguidValue = &GUID_MODEBIAS_HALFWIDTHKATAKANA;
|
|
}
|
|
else if (imc->fdwConversion & IME_CMODE_NATIVE)
|
|
{
|
|
pguidValue = &GUID_MODEBIAS_HALFWIDTHALPHANUMERIC;
|
|
LANGID langid;
|
|
ptls->pAImeProfile->GetLangId(&langid);
|
|
if (langid == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT))
|
|
{
|
|
if (imc->fdwConversion & IME_CMODE_FULLSHAPE)
|
|
pguidValue = &GUID_MODEBIAS_HIRAGANA;
|
|
else
|
|
pguidValue = &GUID_MODEBIAS_HALFWIDTHALPHANUMERIC;
|
|
}
|
|
else if (langid == MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT))
|
|
{
|
|
if (imc->fdwConversion & IME_CMODE_FULLSHAPE)
|
|
pguidValue = &GUID_MODEBIAS_FULLWIDTHHANGUL;
|
|
else
|
|
pguidValue = &GUID_MODEBIAS_HANGUL;
|
|
}
|
|
else if (PRIMARYLANGID(langid) == LANG_CHINESE)
|
|
{
|
|
pguidValue = &GUID_MODEBIAS_CHINESE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (imc->fdwConversion & IME_CMODE_FULLSHAPE)
|
|
pguidValue = &GUID_MODEBIAS_FULLWIDTHALPHANUMERIC;
|
|
else
|
|
pguidValue = &GUID_MODEBIAS_HALFWIDTHALPHANUMERIC;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We overwrite modebias here....
|
|
//
|
|
if (imc->fdwSentence & IME_SMODE_GUID_NULL) {
|
|
//
|
|
// If extended sentence mode were set on,
|
|
// returns GUID_NULL.
|
|
// No returns any MODEBIAS.
|
|
//
|
|
// Nothing to do. pguidValue might be changed with CMODE
|
|
// pguidValue = &GUID_NULL;
|
|
}
|
|
else if (imc->fdwSentence & IME_SMODE_CONVERSATION)
|
|
pguidValue = &GUID_MODEBIAS_CONVERSATION;
|
|
else if (imc->fdwSentence & IME_SMODE_PLAURALCLAUSE)
|
|
pguidValue = &GUID_MODEBIAS_NAME;
|
|
}
|
|
|
|
if (!GetGUIDATOMFromGUID(m_pLibTLS, *pguidValue, &ga))
|
|
return E_FAIL;
|
|
|
|
pvarValue->vt = VT_I4; // for TfGuidAtom
|
|
pvarValue->lVal = ga;
|
|
}
|
|
if (IsEqualGUID(*pguid, TSATTRID_Text_Orientation))
|
|
{
|
|
// xlate conversion mode, sentence mode to cicero mode bias
|
|
IMCLock imc(ptls->hIMC);
|
|
if (imc.Invalid())
|
|
return E_FAIL;
|
|
|
|
pvarValue->vt = VT_I4;
|
|
pvarValue->lVal = imc->lfFont.A.lfEscapement;
|
|
}
|
|
if (IsEqualGUID(*pguid, TSATTRID_Text_VerticalWriting))
|
|
{
|
|
// xlate conversion mode, sentence mode to cicero mode bias
|
|
IMCLock imc(ptls->hIMC);
|
|
if (imc.Invalid())
|
|
return E_FAIL;
|
|
|
|
LOGFONTW font;
|
|
if (SUCCEEDED(ptls->pAImm->GetCompositionFontW(ptls->hIMC, &font))) {
|
|
pvarValue->vt = VT_BOOL;
|
|
pvarValue->lVal = (imc->lfFont.W.lfFaceName[0] == L'@' ? TRUE : FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
LRESULT
|
|
CInputContextOwnerCallBack::MsImeMouseHandler(
|
|
ULONG uEdge,
|
|
ULONG uQuadrant,
|
|
ULONG dwBtnStatus,
|
|
IMCLock& imc,
|
|
ImmIfIME* ImmIfIme
|
|
)
|
|
{
|
|
return m_pMouseSink->MsImeMouseHandler(uEdge, uQuadrant, dwBtnStatus, imc, ImmIfIme);
|
|
}
|