Пример #1
0
HRESULT CTextService::_HandleCharacterKey(TfEditCookie ec, ITfContext *pContext, WPARAM wParam)
{
	if (!_IsComposing())
		_StartComposition(pContext);
    // 
    // create an instance of the candidate list class.
    // 
    if (_pCandidateList == NULL)
        _pCandidateList = new CCandidateList(this);

    // 
    // The document manager object is not cached. Get it from pContext.
    // 
    ITfDocumentMgr *pDocumentMgr;
    if (pContext->GetDocumentMgr(&pDocumentMgr) == S_OK)
    {
        // 
        // get the composition range.
        // 
        ITfRange *pRange;
        if (_pComposition->GetRange(&pRange) == S_OK)
        {
            _pCandidateList->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange);
            pRange->Release();
        }
        pDocumentMgr->Release();
    }
	
	if (_IsComposing())
		_TerminateComposition(ec, pContext);

	return S_OK;
}
Пример #2
0
HRESULT CTextService::_ShowCandidateList(TfEditCookie ec, ITfContext *pContext, BOOL reg, BOOL comp)
{
	HRESULT hr = E_FAIL;

	try
	{
		if(_pCandidateList == NULL)
		{
			_pCandidateList = new CCandidateList(this);
		}

		ITfDocumentMgr *pDocumentMgr;
		if(pContext->GetDocumentMgr(&pDocumentMgr) == S_OK)
		{
			ITfRange *pRange;
			if(_IsComposing() && _pComposition->GetRange(&pRange) == S_OK)
			{
				hr = _pCandidateList->_StartCandidateList(_ClientId, pDocumentMgr, pContext, ec, pRange, reg, comp);
				SafeRelease(&pRange);
			}
			SafeRelease(&pDocumentMgr);
		}

		if(hr != S_OK)
		{
			_ResetStatus();
			_CancelComposition(ec, pContext);
		}
	}
	catch(...)
	{
	}

	return hr;
}
Пример #3
0
BOOL CTextService::_GetVertical(TfEditCookie ec, ITfContext *pContext)
{
	BOOL ret = FALSE;

	if(pContext != NULL)
	{
		ITfRange *pRange;
		if(_IsComposing() && _pComposition->GetRange(&pRange) == S_OK)
		{
			ITfReadOnlyProperty *pReadOnlyProperty;
			if(pContext->GetAppProperty(TSATTRID_Text_VerticalWriting, &pReadOnlyProperty) == S_OK)
			{
				VARIANT var;
				if(pReadOnlyProperty->GetValue(ec, pRange, &var) == S_OK)
				{
					if(var.vt == VT_BOOL)
					{
						ret = var.boolVal;
					}
				}
				SafeRelease(&pReadOnlyProperty);
			}
			SafeRelease(&pRange);
		}
	}

	return ret;
}
Пример #4
0
STDAPI CTextService::OnTestKeyDown(ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
	if(pfEaten == NULL)
	{
		return E_INVALIDARG;
	}

	int eaten = _IsKeyEaten(pic, wParam, lParam, TRUE, TRUE);
	if(eaten == -1)
	{
		*pfEaten = TRUE;
		return S_OK;
	}
	*pfEaten = (eaten == TRUE);

	_EndInputModeWindow();

	if(!_IsKeyboardDisabled() && _IsKeyboardOpen() && !_IsComposing())
	{
		WCHAR ch = _GetCh((BYTE)wParam);
		if(_IsKeyVoid(ch, (BYTE)wParam))
		{
			_GetActiveFlags();
			_UpdateLanguageBar();
		}
	}

	return S_OK;
}
Пример #5
0
HRESULT COVTSF::_HandleCompositionBackspace(TfEditCookie ec, _In_ ITfContext *pContext)
{
    ITfRange* pRangeComposition = nullptr;
    TF_SELECTION tfSelection;
    ULONG fetched = 0;
    BOOL isCovered = TRUE;

    // Start the new (std::nothrow) compositon if there is no composition.
    if (!_IsComposing())
    {
        return S_OK;
    }

    // first, test where a keystroke would go in the document if we did an insert
    if (FAILED(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) || fetched != 1)
    {
        return S_FALSE;
    }

    // is the insertion point covered by a composition?
    if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
    {
        isCovered = _IsRangeCovered(ec, tfSelection.range, pRangeComposition);

        pRangeComposition->Release();

        if (!isCovered)
        {
            goto Exit;
        }
    }

    //
    // Add virtual key to composition processor engine
    //
    CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
    pCompositionProcessorEngine = _pCompositionProcessorEngine;

    DWORD_PTR vKeyLen = pCompositionProcessorEngine->GetVirtualKeyLength();

    if (vKeyLen)
    {
        pCompositionProcessorEngine->RemoveVirtualKey(vKeyLen - 1);

        if (pCompositionProcessorEngine->GetVirtualKeyLength())
        {
            _HandleCompositionInputWorker(pCompositionProcessorEngine, ec, pContext);
        }
        else
        {
            _HandleCancel(ec, pContext);
        }
    }

Exit:
    tfSelection.range->Release();
    return S_OK;
}
STDAPI CTextService::OnEndEdit(ITfContext *pContext, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
{
    BOOL fSelectionChanged;
    IEnumTfRanges *pEnumTextChanges;
    ITfRange *pRange;

    //
    // did the selection change?
    // The selection change includes the movement of caret as well. 
    // The caret position is represent as the empty selection range when
    // there is no selection.
    //
    if (pEditRecord->GetSelectionStatus(&fSelectionChanged) == S_OK &&
        fSelectionChanged)
    {
        // If the selection is moved to out side of the current composition,
        // we terminate the composition. This TextService supports only one
        // composition in one context object.
        if (_IsComposing())
        {
            TF_SELECTION tfSelection;
            ULONG cFetched;

            if (pContext->GetSelection(ecReadOnly, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) == S_OK && cFetched == 1)
            {
                ITfRange *pRangeComposition;
                // is the insertion point covered by a composition?
                if (_pComposition->GetRange(&pRangeComposition) == S_OK)
                {
                    if (!IsRangeCovered(ecReadOnly, tfSelection.range, pRangeComposition))
                    {
                       _EndComposition(pContext);
                    }

                    pRangeComposition->Release();
                }
            }
        }
    }

    // text modification?
    if (pEditRecord->GetTextAndPropertyUpdates(TF_GTP_INCL_TEXT, NULL, 0, &pEnumTextChanges) == S_OK)
    {
        if (pEnumTextChanges->Next(1, &pRange, NULL) == S_OK)
        {
            //
            // pRange is the updated range.
            //

            pRange->Release();
        }

        pEnumTextChanges->Release();
    }

    return S_OK;
}
Пример #7
0
HRESULT CTextService::_HandleCharacterKey(TfEditCookie ec, ITfContext *pContext, WPARAM wParam)
{
    ITfRange *pRangeComposition;
    TF_SELECTION tfSelection;
    ULONG cFetched;
    WCHAR ch;
    BOOL fCovered;

    // Start the new compositon if there is no composition.
    OutputDebugString("test compositing");
    if (!_IsComposing())
        _StartComposition(pContext);

    OutputDebugString("after test compositing");
    //
    // Assign VK_ value to the char. So the inserted the character is always
    // uppercase.
    //
    ch = (WCHAR)wParam;

    // first, test where a keystroke would go in the document if an insert is done
    if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1)
        return S_FALSE;

    // is the insertion point covered by a composition?
    if (_pComposition->GetRange(&pRangeComposition) == S_OK)
    {
        fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition);

        pRangeComposition->Release();

        if (!fCovered)
        {
            goto Exit;
        }
    }

    // insert the text
    // use SetText here instead of InsertTextAtSelection because a composition was already started
    //Don't allow to the app to adjust the insertion point inside the composition
    if (tfSelection.range->SetText(ec, 0, &ch, 1) != S_OK)
        goto Exit;

    // update the selection, make it an insertion point just past
    // the inserted text.
    tfSelection.range->Collapse(ec, TF_ANCHOR_END);
    pContext->SetSelection(ec, 1, &tfSelection);

    //
    // set the display attribute to the composition range.
    //
    _SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeInput);

Exit:
    tfSelection.range->Release();
    return S_OK;
}
Пример #8
0
HRESULT COVTSF::_HandleCompositionFinalize(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isCandidateList)
{
    HRESULT hr = S_OK;

    if (isCandidateList && _pCandidateListUIPresenter)
    {
        // Finalize selected candidate string from CCandidateListUIPresenter
        DWORD_PTR candidateLen = 0;
        const WCHAR *pCandidateString = nullptr;

        candidateLen = _pCandidateListUIPresenter->_GetSelectedCandidateString(&pCandidateString);

        CStringRange candidateString;
        candidateString.Set(pCandidateString, candidateLen);

        if (candidateLen)
        {
            // Finalize character
            hr = _AddCharAndFinalize(ec, pContext, &candidateString);
            if (FAILED(hr))
            {
                return hr;
            }
        }
    }
    else
    {
        // Finalize current text store strings
        if (_IsComposing())
        {
            ULONG fetched = 0;
            TF_SELECTION tfSelection;

            if (FAILED(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) || fetched != 1)
            {
                return S_FALSE;
            }

            ITfRange* pRangeComposition = nullptr;
            if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
            {
                if (_IsRangeCovered(ec, tfSelection.range, pRangeComposition))
                {
                    _EndComposition(pContext);
                }

                pRangeComposition->Release();
            }

            tfSelection.range->Release();
        }
    }

    _HandleCancel(ec, pContext);

    return S_OK;
}
Пример #9
0
BOOL CTextService::_IsKeyEaten(ITfContext *pContext, WPARAM wParam)
{
    // if the keyboard is disabled, keys are not consumed.
    if (_IsKeyboardDisabled())
        return FALSE;

    // if the keyboard is closed, keys are not consumed.
    if (!_IsKeyboardOpen())
        return FALSE;

    //
    // The text service key handler does not do anything while the candidate
    // window is shown.
    // The candidate list handles the keys through ITfContextKeyEventSink.
    //
    if (_pCandidateList &&
        _pCandidateList->_IsContextCandidateWindow(pContext))
    {
        return FALSE;
    }

    // eat only keys that CKeyHandlerEditSession can hadles.
    switch (wParam)
    {
        case VK_LEFT:
        case VK_RIGHT:
        case VK_RETURN:
		case VK_SPACE:
		case VK_BACK:
			if (_IsComposing())
                return TRUE;
			return FALSE;
		case 0xC0:
		case 0xBD:
		case 0xBB:
		case 0xDB:
		case 0xDD:
		case 0xDC:
		case 0xBA:
		case 0xDE:
		case 0xBC:
		case 0xBE:
		case 0xBF:
			return TRUE;		
	}
	if (GetKeyState(VK_MENU) & 0x8000)
		return FALSE;
	else if (GetKeyState(VK_CONTROL) & 0x8000)
		return FALSE;
	else if (wParam >= VK_NUMPAD0 && wParam <= VK_NUMPAD9)
		return FALSE;
	else if ( (wParam >= '0' && wParam <= '9') || (wParam >= 'A' && wParam <= 'Z') )
		return TRUE;

    return FALSE;
}
Пример #10
0
void CDIME::OnKeyboardClosed()
{
	debugPrint(L"CDIME::OnKeyboardClosed()\n");
	// switching to English (native) mode delete the phrase candidate window before exting.
	_isChinese = FALSE;
	if(_IsComposing()) 
	{
		_EndComposition(_pContext);
	}
	_DeleteCandidateList(TRUE,_pContext);
}
Пример #11
0
void CDIME::OnSwitchedToHalfShape()
{
	debugPrint(L"CDIME::OnSwitchedToHalfShape()\n");
	_isFullShape = FALSE;
	if(_IsComposing()) 
	{
		_EndComposition(_pContext);
	}
	_DeleteCandidateList(TRUE,_pContext);
	if (CConfig::GetDoubleSingleByteMode() != DOUBLE_SINGLE_BYTE_SHIFT_SPACE)
		CConfig::SetDoubleSingleByteMode(DOUBLE_SINGLE_BYTE_ALWAYS_SINGLE);
}
Пример #12
0
/* Update Composition */
void WeaselTSF::_UpdateComposition(ITfContext *pContext)
{
	// get commit string from server
	std::wstring commit;
	weasel::Status status;
	weasel::Config config;

	auto context = std::make_shared<weasel::Context>();

	weasel::ResponseParser parser(&commit, context.get(), &status, &config);

	bool ok = m_client.GetResponseData(std::ref(parser));

	if (ok)
	{
		bool composing = _IsComposing();
		if (!commit.empty())
		{
			// 修复顶字上屏的吞字问题:
			// 顶字上屏(如五笔 4 码上屏时),当候选词数 > 1 时,
			// 第 5 码输入时会将首选项顶屏。
			// 此时由于第五码的输入,composition 应是开启的,同时也要在输入处插入顶字。
			// 这里先关闭上一个字的 composition,然后为后续输入开启一个新 composition。
			// 有点 dirty 但是 it works ...
			if (composing) {
				_EndComposition(pContext);
				composing = false;
			}
			_InsertText(pContext, commit);
		}
		if (status.composing && !composing)
		{
			if (!_fCUASWorkaroundTested)
			{
				/* Test if we need to apply the workaround */
				_UpdateCompositionWindow(pContext);
			}
			else if (!_fCUASWorkaroundEnabled || config.inline_preedit)
			{
				/* Workaround not applied, update candidate window position at this point. */
				_UpdateCompositionWindow(pContext);
			}
			_StartComposition(pContext, _fCUASWorkaroundEnabled && !config.inline_preedit);
		}
		else if (!status.composing && composing) {
			_EndComposition(pContext);
			composing = false;
		}
		if (composing && config.inline_preedit)
			_ShowInlinePreedit(pContext, context);
	}
}
Пример #13
0
HRESULT CDIME::_ProbeCompositionRangeNotification(_In_ TfEditCookie ec, _In_ ITfContext *pContext)
{
	debugPrint(L"CDIME::_ProbeCompositionRangeNotification(), \n");


	HRESULT hr = S_OK;
	if(!_IsComposing())
		_StartComposition(pContext);
	
	hr = E_FAIL;
    ULONG fetched = 0;
    TF_SELECTION tfSelection;

    if ( pContext == nullptr || (hr = pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) != S_OK || fetched != 1 ||tfSelection.range==nullptr)
	{
		_TerminateComposition(ec,pContext);
        return hr;
	}
	tfSelection.range->Release();
   
	
	ITfRange *pRange;
	ITfContextView* pContextView;
	ITfDocumentMgr* pDocumgr;
	if (_pComposition&&SUCCEEDED(_pComposition->GetRange(&pRange)) && pRange)
	{
		if(pContext && SUCCEEDED(pContext->GetActiveView(&pContextView)) && pContextView)
		{
			if(pContext && SUCCEEDED( pContext->GetDocumentMgr(&pDocumgr)) && pDocumgr && _pThreadMgr &&_pUIPresenter)
			{
				ITfDocumentMgr* pFocusDocuMgr;
				_pThreadMgr->GetFocus(&pFocusDocuMgr);
				if(pFocusDocuMgr == pDocumgr)
				{
					_pUIPresenter->_StartLayout(pContext, ec, pRange);
					_pUIPresenter->_MoveUIWindowsToTextExt();
				}
				else 
					_pUIPresenter->ClearNotify();

				pDocumgr->Release();
			}
		pContextView->Release();
		}
		pRange->Release();
	}


    
	_TerminateComposition(ec,pContext);
	return hr;
}
STDAPI CSampleIME::OnEndEdit(__RPC__in_opt ITfContext *pContext, TfEditCookie ecReadOnly, __RPC__in_opt ITfEditRecord *pEditRecord)
{
    BOOL isSelectionChanged;

    //
    // did the selection change?
    // The selection change includes the movement of caret as well. 
    // The caret position is represent as the empty selection range when
    // there is no selection.
    //
    if (pEditRecord == nullptr)
    {
        return E_INVALIDARG;
    }
    if (SUCCEEDED(pEditRecord->GetSelectionStatus(&isSelectionChanged)) &&
        isSelectionChanged)
    {
        // If the selection is moved to out side of the current composition,
        // we terminate the composition. This TextService supports only one
        // composition in one context object.
        if (_IsComposing())
        {
            TF_SELECTION tfSelection;
            ULONG fetched = 0;

            if (pContext == nullptr)
            {
                return E_INVALIDARG;
            }
            if (FAILED(pContext->GetSelection(ecReadOnly, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) || fetched != 1)
            {
                return S_FALSE;
            }

            ITfRange* pRangeComposition = nullptr;
            if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
            {
                if (!_IsRangeCovered(ecReadOnly, tfSelection.range, pRangeComposition))
                {
                    _EndComposition(pContext);
                }

                pRangeComposition->Release();
            }

            tfSelection.range->Release();
        }
    }

    return S_OK;
}
Пример #15
0
void CTextService::_ClearCompositionDisplayAttributes(TfEditCookie ec, ITfContext *pContext)
{
	ITfRange *pRange;
	if(_IsComposing() && _pComposition->GetRange(&pRange) == S_OK)
	{
		ITfProperty *pProperty;
		if(pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pProperty) == S_OK)
		{
			pProperty->Clear(ec, pRange);
			SafeRelease(&pProperty);
		}
		SafeRelease(&pRange);
	}
}
Пример #16
0
HRESULT COVTSF::_HandleCompositionInput(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch)
{
    ITfRange* pRangeComposition = nullptr;
    TF_SELECTION tfSelection;
    ULONG fetched = 0;
    BOOL isCovered = TRUE;

    CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
    pCompositionProcessorEngine = _pCompositionProcessorEngine;

    if ((_pCandidateListUIPresenter != nullptr) && (_candidateMode != CANDIDATE_INCREMENTAL))
    {
        _HandleCompositionFinalize(ec, pContext, FALSE);
    }

    // Start the new (std::nothrow) compositon if there is no composition.
    if (!_IsComposing())
    {
        _StartComposition(pContext);
    }

    // first, test where a keystroke would go in the document if we did an insert
    if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched) != S_OK || fetched != 1)
    {
        return S_FALSE;
    }

    // is the insertion point covered by a composition?
    if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
    {
        isCovered = _IsRangeCovered(ec, tfSelection.range, pRangeComposition);

        pRangeComposition->Release();

        if (!isCovered)
        {
            goto Exit;
        }
    }

    // Add virtual key to composition processor engine
    pCompositionProcessorEngine->AddVirtualKey(wch);

    _HandleCompositionInputWorker(pCompositionProcessorEngine, ec, pContext);

Exit:
    tfSelection.range->Release();
    return S_OK;
}
Пример #17
0
void CTextService::_ClearCompositionDisplayAttributes(TfEditCookie ec, ITfContext *pContext)
{
	if(_IsComposing())
	{
		ITfRange *pRange = nullptr;
		if(SUCCEEDED(_pComposition->GetRange(&pRange)) && (pRange != nullptr))
		{
			ITfProperty *pProperty = nullptr;
			if(SUCCEEDED(pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pProperty)) && (pProperty != nullptr))
			{
				pProperty->Clear(ec, pRange);
				SafeRelease(&pProperty);
			}
			SafeRelease(&pRange);
		}
	}
}
Пример #18
0
STDAPI CTextService::OnEndEdit(ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord)
{
	if(_IsComposing() && pic != nullptr)
	{
		ITfRange *pRange = nullptr;
		if(SUCCEEDED(_pComposition->GetRange(&pRange)) && (pRange != nullptr))
		{
			// clear when auto completion
			BOOL fEmpty = FALSE;
			if(SUCCEEDED(pRange->IsEmpty(ecReadOnly, &fEmpty)) && fEmpty)
			{
				if(!roman.empty() || !kana.empty())
				{
					_ResetStatus();
					_EndComposition(pic);
				}
			}

			// reposition candidate window
			if(_pCandidateList != nullptr)
			{
				ITfContextView *pContextView = nullptr;
				if(SUCCEEDED(pic->GetActiveView(&pContextView)) && (pContextView != nullptr))
				{
					RECT rc = {};
					BOOL fClipped;
					if(SUCCEEDED(pContextView->GetTextExt(ecReadOnly, pRange, &rc, &fClipped)))
					{
						_pCandidateList->_Move(&rc, ecReadOnly, pic);
					}

					SafeRelease(&pContextView);
				}
			}

			SafeRelease(&pRange);
		}
	}

	return S_OK;
}
Пример #19
0
void CTextService::_UpdateLanguageBar(BOOL showinputmode)
{
    if(_pLangBarItem != nullptr)
    {
        _pLangBarItem->_Update();
    }

    if(_pLangBarItemI != nullptr)
    {
        _pLangBarItemI->_Update();
    }

    if(showinputmode && _ShowInputMode && !_IsComposing())
    {
        _StartInputModeWindow();
    }
    else
    {
        _EndInputModeWindow();
    }
}
BOOL CTextService::_IsKeyEaten(ITfContext *pContext, WPARAM wParam)
{
    // if the keyboard is disabled, we don't eat keys.
    if (_IsKeyboardDisabled())
        return FALSE;

    // if the keyboard is closed, we don't eat keys.
    if (!_IsKeyboardOpen())
        return FALSE;

    //
    // The text service key handler does not do anything while the candidate
    // window is shown.
    // The candidate list handles the keys through ITfContextKeyEventSink.
    //
    if (_pCandidateList &&
        _pCandidateList->_IsContextCandidateWindow(pContext))
    {
        return FALSE;
    }

    // eat only keys that CKeyHandlerEditSession can hadles.
    switch (wParam)
    {
        case VK_LEFT:
        case VK_RIGHT:
        case VK_RETURN:
        case VK_SPACE:
            if (_IsComposing())
                return TRUE;
            return FALSE;
    }

    if (wParam >= 'A' && wParam <= 'Z')
        return TRUE;

    return FALSE;
}
HRESULT CTextService::_HandleCharShift(TfEditCookie ec, ITfContext *pContext)
{
	if(showentry || (!inputkey && !kana.empty() && roman.empty()))
	{
		_EndCompletionList(ec, pContext);

		//leave composition
		cursoridx = kana.size();
		_Update(ec, pContext, TRUE);
		if(pContext != NULL)
		{
			ITfRange *pRange;
			if(_IsComposing() && _pComposition->GetRange(&pRange) == S_OK)
			{
				pRange->Collapse(ec, TF_ANCHOR_END);
				_pComposition->ShiftStart(ec, pRange);
				SafeRelease(&pRange);
			}
		}
		_ResetStatus();
	}

	return S_OK;
}
Пример #22
0
int CTextService::_IsKeyEaten(ITfContext *pContext, WPARAM wParam, LPARAM lParam, bool isKeyDown, bool isTest)
{
	if(_IsKeyboardDisabled())
	{
		return FALSE;
	}

	if(!_IsKeyboardOpen())
	{
		return FALSE;
	}

	//カーソル直前文字列削除をBSを送って消す場合のDeleter用処理。
	//(TSFによるカーソル直前文字列削除ができなかった場合用。)
	//mozcのwin32/tip/tip_keyevent_handler.ccから。
	bool is_key_down = isKeyDown;
	if(isTest)
	{
		const mozc::win32::LParamKeyInfo key_info(lParam);
		is_key_down = key_info.IsKeyDownInImeProcessKey();
	}
	const mozc::win32::VKBackBasedDeleter::ClientAction vk_back_action =
		deleter.OnKeyEvent(wParam, is_key_down, isTest);

	switch(vk_back_action)
	{
	case mozc::win32::VKBackBasedDeleter::DO_DEFAULT_ACTION:
		// do nothing.
		break;
	case mozc::win32::VKBackBasedDeleter::CALL_END_DELETION_THEN_DO_DEFAULT_ACTION:
		deleter.EndDeletion();
		break;
	case mozc::win32::VKBackBasedDeleter::SEND_KEY_TO_APPLICATION:
		if(is_key_down && isTest && !postbuf.empty())
		{
			postbuf.pop_back();
		}
		return FALSE; // Do not consume this key.
	case mozc::win32::VKBackBasedDeleter::CONSUME_KEY_BUT_NEVER_SEND_TO_SERVER:
		return -1; // Consume this key but do not send this key to server.
	case mozc::win32::VKBackBasedDeleter::CALL_END_DELETION_BUT_NEVER_SEND_TO_SERVER:
		if(!isTest)
		{
			deleter.EndDeletion();
			return -1;
		}
		else
		{
			return FALSE;
		}
	case mozc::win32::VKBackBasedDeleter::APPLY_PENDING_STATUS:
		if(!isTest)
		{
			_InvokeKeyHandler(pContext, wParam, lParam, SKK_AFTER_DELETER);
			return -1;
		}
		else
		{
			return FALSE;
		}
	default:
		break;
	}

	if(_pCandidateList && _pCandidateList->_IsContextCandidateWindow(pContext))
	{
		return FALSE;
	}

	if(_IsComposing() || !cx_showromancomp && !roman.empty())
	{
		if(inputmode != im_ascii)
		{
			return TRUE;
		}
	}

	SHORT vk_ctrl = GetKeyState(VK_CONTROL) & 0x8000;
	SHORT vk_kana = GetKeyState(VK_KANA) & 0x0001;

	WCHAR ch = _GetCh((BYTE)wParam);
	BYTE sf = _GetSf((BYTE)wParam, ch);

	//確定状態で処理する機能
	switch(inputmode)
	{
	case im_jlatin:
	case im_ascii:
		switch(sf)
		{
		case SKK_JMODE:
		case SKK_OTHERIME:
			return TRUE;
			break;
		default:
			break;
		}
		break;
	case im_hiragana:
	case im_katakana:
		switch(sf)
		{
		case SKK_CONV_POINT:
		case SKK_KANA:
		case SKK_CONV_CHAR:
		case SKK_JLATIN:
		case SKK_ASCII:
		case SKK_ABBREV:
		case SKK_OTHERIME:
			return TRUE;
			break;
		case SKK_VIESC:
			inputmode = im_ascii;
			_UpdateLanguageBar();
			postbuf.clear();
			return FALSE;
			break;
		default:
			break;
		}
		break;
	case im_katakana_ank:
		switch(sf)
		{
		case SKK_KANA:
		case SKK_CONV_CHAR:
		case SKK_JLATIN:
		case SKK_ASCII:
		case SKK_OTHERIME:
			return TRUE;
			break;
		case SKK_VIESC:
			inputmode = im_ascii;
			_UpdateLanguageBar();
			postbuf.clear();
			return FALSE;
		default:
			break;
		}
		break;
	default:
		break;
	}

	//無効
	if(_IsKeyVoid(ch, (BYTE)wParam))
	{
		return TRUE;
	}

	//処理しないCtrlキー
	if(vk_ctrl != 0)
	{
		postbuf.clear();
		return FALSE;
	}

	//ASCIIモード、かなキーロックOFF
	if(inputmode == im_ascii && vk_kana == 0)
	{
		return FALSE;
	}

	if(ch >= L'\x20')
	{
		return TRUE;
	}

	if(!postbuf.empty())
	{
		if((wParam == VK_BACK || wParam == VK_LEFT) && is_key_down && isTest)
		{
			postbuf.pop_back();
		}
		else
		{
			switch(wParam)
			{
			//case VK_LEFT:
			case VK_RIGHT:
			case VK_UP:
			case VK_DOWN:
			case VK_HOME:
			case VK_END:
			case VK_PRIOR:
			case VK_NEXT:
				if(is_key_down && isTest)
				{
					postbuf.clear();
				}
				break;
			default:
				break;
			}
		}
	}

	return FALSE;
}
Пример #23
0
HRESULT CTextService::_HandleKey(TfEditCookie ec, ITfContext *pContext, WPARAM wParam)
{

    /*
     * FIXME: the following keys are not handled:
     * shift left		VK_LSHIFT
     * shift right		VK_RSHIFT
     * caps lock		VK_CAPITAL
     * page up			VK_PRIOR
     * page down		VK_NEXT
     * ctrl num
     * shift space
     * numlock num		VK_NUMLOCK
	 */

    if (('A' <= wParam && wParam <= 'Z')) {
            chewing_handle_Default(mChewingContext, wParam - 'A' + 'a');
    } else if ('0' <= wParam && wParam <= '9') {
            chewing_handle_Default(mChewingContext, wParam);
    } else {
        switch(wParam) {
            case VK_OEM_COMMA:
                chewing_handle_Default(mChewingContext, ',');
                break;

            case VK_OEM_MINUS:
                chewing_handle_Default(mChewingContext, '-');
                break;

            case VK_OEM_PERIOD:
                chewing_handle_Default(mChewingContext, '.');
                break;

            case VK_OEM_1:
                chewing_handle_Default(mChewingContext, ';');
                break;

            case VK_OEM_2:
                chewing_handle_Default(mChewingContext, '/');
                break;

            case VK_OEM_3:
                chewing_handle_Default(mChewingContext, '`');
                break;

            case VK_SPACE:
                chewing_handle_Space(mChewingContext);
                break;

            case VK_ESCAPE:
                chewing_handle_Esc(mChewingContext);
                break;

            case VK_RETURN:
                chewing_handle_Enter(mChewingContext);
                break;

            case VK_DELETE:
                chewing_handle_Del(mChewingContext);
                break;

            case VK_BACK:
                chewing_handle_Backspace(mChewingContext);
                break;

            case VK_UP:
                chewing_handle_Up(mChewingContext);
                break;

            case VK_DOWN:
                chewing_handle_Down(mChewingContext);

            case VK_LEFT:
                chewing_handle_Left(mChewingContext);
                break;

            case VK_RIGHT:
                chewing_handle_Right(mChewingContext);
                break;

            case VK_HOME:
                chewing_handle_Home(mChewingContext);
                break;

            case VK_END:
                chewing_handle_End(mChewingContext);
                break;

            default:
                return S_OK;
        }
    }

    // Remove old candidate list. We will create a new one if necessary.
    _pCandidateList->_EndCandidateList();

    ChewingCandidates candidate(mChewingContext);
    if (!candidate.IsEmpty()) {
        _SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeConverted);

        //
        // The document manager object is not cached. Get it from pContext.
        //
        ITfDocumentMgr *pDocumentMgr;
        if (pContext->GetDocumentMgr(&pDocumentMgr) == S_OK)
        {
            //
            // get the composition range.
            //
            ITfRange *pRange;
            if (_pComposition->GetRange(&pRange) == S_OK)
            {
                _pCandidateList->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, candidate);
                pRange->Release();
            }
            pDocumentMgr->Release();
        }
        return S_OK;
    }

    ChewingString commit(mChewingContext, CHEWING_STRING_COMMIT);
    if (!commit.IsEmpty()) {
        // FIXME: Need a better way to submit a string
        if (!_IsComposing())
            _StartComposition(pContext);

        ULONG cFetched;
        BOOL fCovered;
        TF_SELECTION tfSelection;

        // FIXME: Why we need this here?
        // first, test where a keystroke would go in the document if an insert is done
        if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1)
            return S_FALSE;

        // FIXME: Why we need this here?
        // is the insertion point covered by a composition?
        ITfRange *pRangeComposition;
        if (_pComposition->GetRange(&pRangeComposition) == S_OK)
        {
            fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition);

            pRangeComposition->Release();

            if (!fCovered)
            {
                goto End3;
            }
        }

        if (tfSelection.range->SetText(ec, 0, commit.GetString(), commit.GetLength()) != S_OK)
            goto End3;

        _TerminateComposition(ec, pContext);
End3: // FIXME: RAII?
        tfSelection.range->Release();
    }

    /*
     * Composition is mapped to preedit buffer + zuin buffer
     */
    ChewingString preedit_zuin(mChewingContext, CHEWING_STRING_PREEDIT_ZUIN);
    if (preedit_zuin.IsEmpty()) {
        // Remove composition
        if (_IsComposing())
        {
            ULONG cFetched;
            BOOL fCovered;
            TF_SELECTION tfSelection;

            // FIXME: Why we need this here?
            // first, test where a keystroke would go in the document if an insert is done
            if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1)
                return S_FALSE;

            // FIXME: Why we need this here?
            // is the insertion point covered by a composition?
            ITfRange *pRangeComposition;
            if (_pComposition->GetRange(&pRangeComposition) == S_OK)
            {
                fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition);

                pRangeComposition->Release();

                if (!fCovered)
                {
                    goto End;
                }
            }

            // Empties the composition
            tfSelection.range->SetText(ec, 0, L"", 0);

            _TerminateComposition(ec, pContext);
End: // FIXME: RAII?
            tfSelection.range->Release();
        }
    } else {
        if (!_IsComposing())
            _StartComposition(pContext);

        ULONG cFetched;
        BOOL fCovered;
        TF_SELECTION tfSelection;
        // FIXME: Why we need this here?
        // first, test where a keystroke would go in the document if an insert is done
        if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK || cFetched != 1)
            return S_FALSE;

        // FIXME: Why we need this here?
        // is the insertion point covered by a composition?
        ITfRange *pRangeComposition;
        if (_pComposition->GetRange(&pRangeComposition) == S_OK)
        {
            fCovered = IsRangeCovered(ec, tfSelection.range, pRangeComposition);

            pRangeComposition->Release();

            if (!fCovered)
            {
                goto End2;
            }
        }
        if (tfSelection.range->SetText(ec, 0, preedit_zuin.GetString(), preedit_zuin.GetLength()) != S_OK)
            goto End2;

        _SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeInput);
End2: // FIXME: RAII?
        tfSelection.range->Release();
    }

    return S_OK;
}
Пример #24
0
BOOL CTextService::_IsKeyEaten(ITfContext *pContext, WPARAM wParam)
{
	if(_IsKeyboardDisabled())
	{
		return FALSE;
	}

	if(!_IsKeyboardOpen())
	{
		return FALSE;
	}

	if(_pCandidateList && _pCandidateList->_IsContextCandidateWindow(pContext))
	{
		return FALSE;
	}

	if(_IsComposing())
	{
		if(inputmode != im_ascii && !_pInputModeWindow)
		{
			return TRUE;
		}
	}

	SHORT vk_ctrl = GetKeyState(VK_CONTROL) & 0x8000;
	SHORT vk_kana = GetKeyState(VK_KANA) & 0x0001;

	WCHAR ch = _GetCh((BYTE)wParam);
	BYTE sf = _GetSf((BYTE)wParam, ch);

	//確定状態で処理する機能
	switch(inputmode)
	{
	case im_jlatin:
	case im_ascii:
		switch(sf)
		{
		case SKK_JMODE:
			return TRUE;
			break;
		default:
			break;
		}
		break;
	case im_hiragana:
	case im_katakana:
		switch(sf)
		{
		case SKK_CONV_POINT:
		case SKK_KANA:
		case SKK_CONV_CHAR:
		case SKK_JLATIN:
		case SKK_ASCII:
		case SKK_ABBREV:
			return TRUE;
			break;
		default:
			break;
		}
		break;
	case im_katakana_ank:
		switch(sf)
		{
		case SKK_KANA:
		case SKK_CONV_CHAR:
		case SKK_JLATIN:
		case SKK_ASCII:
			return TRUE;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}

	//無効
	if(_IsKeyVoid(ch, (BYTE)wParam))
	{
		return TRUE;
	}

	//処理しないCtrlキー
	if(vk_ctrl)
	{
		return FALSE;
	}

	//ASCIIモード、かなキーロック
	if(inputmode == im_ascii && !vk_kana)
	{
		return FALSE;
	}

	if(ch >= L'\x20')
	{
		return TRUE;
	}

	return FALSE;
}
Пример #25
0
HRESULT CTextService::_SetText(TfEditCookie ec, ITfContext *pContext, const std::wstring &text, LONG cchCursor, LONG cchOkuri, BOOL fixed)
{
	TF_SELECTION tfSelection;
	ULONG cFetched = 0;
	LONG cch, cchRes;

	if(pContext == NULL && _pCandidateList != NULL)	//辞書登録用
	{
		_pCandidateList->_SetText(text, fixed, FALSE, FALSE);
		return S_OK;
	}

	if(!_IsComposing())
	{
		if(!_StartComposition(pContext))
		{
			return S_FALSE;
		}
	}

	if(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &cFetched) != S_OK)
	{
		return S_FALSE;
	}

	if(cFetched != 1)
	{
		SafeRelease(&tfSelection.range);
		return S_FALSE;
	}

	ITfRange *pRange;
	if(_IsComposing() && _pComposition->GetRange(&pRange) == S_OK)
	{
		if(_IsRangeCovered(ec, tfSelection.range, pRange))
		{
			pRange->SetText(ec, 0, text.c_str(), (LONG)text.size());

			// shift from end to start.
			// shift over mathematical operators (U+2200-U+22FF) is rejected by OneNote.
			if(cchCursor == 0)
			{
				cchRes = (LONG)cursoridx - (LONG)kana.size();
				if((complement && okuriidx != 0) ||
					(!cx_showmodemark && okuriidx != 0 && cursoridx <= okuriidx && cursoridx < kana.size()))
				{
					cchRes += 1;
				}
			}
			else
			{
				cchRes = cchCursor - (LONG)text.size();
				if(cchRes > 0)
				{
					cchRes = 0;
				}
				else if(cchRes < -(LONG)text.size())
				{
					cchRes = -(LONG)text.size();
				}
			}

			tfSelection.range->ShiftEndToRange(ec, pRange, TF_ANCHOR_END);
			tfSelection.range->ShiftStartToRange(ec, pRange, TF_ANCHOR_END);
			tfSelection.range->ShiftStart(ec, cchRes, &cch, NULL);
			//decide cursor position
			tfSelection.range->Collapse(ec, TF_ANCHOR_START);
			pContext->SetSelection(ec, 1, &tfSelection);

			//composition attribute
			if(!fixed)
			{
				ITfRange *pRangeClone;
				if(pRange->Clone(&pRangeClone) == S_OK)
				{
					pRangeClone->ShiftEndToRange(ec, pRange, TF_ANCHOR_END);
					pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START);

					if(cchCursor == 0 || !showentry)
					{
						if(inputkey)
						{
							_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputMark);
							if(cx_showmodemark)
							{
								pRangeClone->ShiftStart(ec, 1, &cch, NULL);
							}
						}

						if(!display_attribute_series[1] || !inputkey)
						{
							_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputText);
						}

						if(cchOkuri != 0)
						{
							pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START);
							pRangeClone->ShiftStart(ec, cchOkuri, &cch, NULL);
							if(!display_attribute_series[2])
							{
								_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputOkuri);
							}

							if(hintmode && text.find_first_of(CHAR_SKK_HINT) != std::wstring::npos)
							{
								LONG hintpos = (LONG)text.find_first_of(CHAR_SKK_HINT);
								if(cchOkuri < hintpos)
								{
									pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START);
									pRangeClone->ShiftStart(ec, hintpos, &cch, NULL);
									_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeInputText);
								}
							}
						}
					}
					else
					{
						_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvMark);
						if(cx_showmodemark)
						{
							pRangeClone->ShiftStart(ec, 1, &cch, NULL);
						}

						if(!display_attribute_series[4])
						{
							_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvText);
						}

						if(cchOkuri != 0)
						{
							pRangeClone->ShiftStartToRange(ec, pRange, TF_ANCHOR_START);
							pRangeClone->ShiftStart(ec, cchOkuri, &cch, NULL);
							if(!display_attribute_series[5])
							{
								_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvOkuri);
							}
						}

						pRangeClone->ShiftEndToRange(ec, pRange, TF_ANCHOR_END);
						pRangeClone->ShiftStartToRange(ec, tfSelection.range, TF_ANCHOR_END);
						if(!display_attribute_series[6])
						{
							_SetCompositionDisplayAttributes(ec, pContext, pRangeClone, _gaDisplayAttributeConvAnnot);
						}
					}
					SafeRelease(&pRangeClone);
				}
			}

			// for Excel's PHONETIC function
			if(fixed && !text.empty())
			{
				ITfProperty *pProperty;
				if(pContext->GetProperty(GUID_PROP_READING, &pProperty) == S_OK)
				{
					VARIANT var;
					var.vt = VT_BSTR;
					std::wstring phone(kana);
					if(okuriidx == 0)
					{
						switch(inputmode)
						{
						case im_hiragana:
						case im_katakana:
						case im_katakana_ank:
							//接辞
							if(!abbrevmode && kana.size() >= 2)
							{
								if(kana.front() == L'>')
								{
									phone = kana.substr(1);
								}
								else if(kana.back() == L'>')
								{
									phone = kana.substr(0, kana.size() - 1);
								}
							}
							break;
						default:
							break;
						}
					}
					else
					{
						if(kana.size() > (okuriidx + 1))
						{
							phone = kana.substr(0, okuriidx) + kana.substr(okuriidx + 1);
						}
						else if(kana.size() >= okuriidx)
						{
							phone = kana.substr(0, okuriidx);
						}
					}
					if(!phone.empty())
					{
						var.bstrVal = SysAllocString(phone.c_str());
						pProperty->SetValue(ec, pRange, &var);
						SysFreeString(var.bstrVal);
					}
					SafeRelease(&pProperty);
				}
			}
		}

		SafeRelease(&pRange);
	}

	SafeRelease(&tfSelection.range);

	return S_OK;
}
Пример #26
0
HRESULT CDIME::_HandleCandidateWorker(TfEditCookie ec, _In_ ITfContext *pContext)
{

	debugPrint(L"CDIME::_HandleCandidateWorker() \n");
    HRESULT hr = S_OK;
	CStringRange commitString, convertedString;
	CDIMEArray<CCandidateListItem> candidatePhraseList;	
	CStringRange lastChar;
	CStringRange notify;
	
    if (nullptr == _pUIPresenter)
    {
        goto Exit; //should not happen
    }
	
	const WCHAR* pCandidateString = nullptr;
	DWORD_PTR candidateLen = 0;
	BOOL arrayUsingSPCode =FALSE;

	if (!_IsComposing())
		_StartComposition(pContext);

	if (Global::imeMode == IME_MODE_ARRAY)// check if the _strokebuffer is array special code
	{
		candidateLen = _pCompositionProcessorEngine->CollectWordFromArraySpeicalCode(&pCandidateString);
		if(candidateLen) arrayUsingSPCode = TRUE;
	}
	candidateLen = 0;
	candidateLen = _pUIPresenter->_GetSelectedCandidateString(&pCandidateString);
	if (candidateLen == 0)
    {
		if(_candidateMode == CANDIDATE_WITH_NEXT_COMPOSITION || _candidateMode == CANDIDATE_PHRASE)
		{
			_HandleCancel(ec, pContext);
			goto Exit;
		}
		else
		{
			hr = S_FALSE;
			_HandleCancel(ec, pContext);
			DoBeep(BEEP_COMPOSITION_ERROR); //beep for no valid mapping found
			goto Exit;
		}
    }
	if (_pCompositionProcessorEngine->IsArrayShortCode() && candidateLen == 1 && *pCandidateString == 0x2394) // empty position in arry short code table.
	{
		hr = S_FALSE;
		if (Global::imeMode == IME_MODE_PHONETIC)
			DoBeep(BEEP_WARNING);
		else
		{
			if (CConfig::GetClearOnBeep()) _HandleCancel(ec, pContext);
			DoBeep(BEEP_COMPOSITION_ERROR); //beep for no valid mapping found
		}
		goto Exit;
	}
	
	
	StringCchCopy(_commitString, 1, L"\0");
	StringCchCatN(_commitString, MAX_COMMIT_LENGTH, pCandidateString, candidateLen);
	commitString.Set(_commitString, candidateLen);
	//_commitString = commitString;
	
	PWCHAR pwch = new (std::nothrow) WCHAR[2];  // pCandidateString will be destroyed after _detelteCanddiateList was called.
	if(candidateLen > 1)
	{	
		StringCchCopyN(pwch, 2, pCandidateString + candidateLen -1, 1); 
	}else // cnadidateLen ==1
	{
		StringCchCopyN(pwch, 2, pCandidateString, 1); 	
	}
	lastChar.Set(pwch, 1 );
	//-----------------do reverse conversion notify. We should not show notify in UI-less mode, thus cancel reverse conversion notify in UILess Mode
	if (!_IsUILessMode())
	{
		if (_pITfReverseConversion[Global::imeMode])
		{
			_AsyncReverseConversion(pContext); //asynchronized the reverse conversion with editsession for better perfomance
		}
		//-----------------or complete real key code when input with wildcard
		else if (_isCandidateWithWildcard)
		{
			const WCHAR* pCandidateKeyCode = nullptr;
			DWORD_PTR keyCodeLen = _pUIPresenter->_GetSelectedCandidateKeyCode(&pCandidateKeyCode);
			StringCchCopy(_commitKeyCode, 1, L"\0");
			StringCchCatN(_commitKeyCode, MAX_KEY_LENGTH, pCandidateKeyCode, keyCodeLen);
			CStringRange commitKeyCode, convertedKeyCode;
			_pCompositionProcessorEngine->GetReadingString(&convertedKeyCode, NULL, &commitKeyCode.Set(_commitKeyCode, wcslen(_commitKeyCode)));
			_pUIPresenter->ShowNotifyText(&convertedKeyCode);
		}

	}
	//-----------------do  array spcial code notify. We should not show notify in UI-less mode, thus cancel forceSP mode in UILess Mode---
	BOOL ArraySPFound = FALSE;            
	if(Global::imeMode == IME_MODE_ARRAY && !_IsUILessMode()  && !arrayUsingSPCode && (CConfig::GetArrayForceSP() || CConfig::GetArrayNotifySP()))
	{
		CStringRange specialCode;
		CStringRange notifyText;
		ArraySPFound = _pCompositionProcessorEngine->GetArraySpeicalCodeFromConvertedText(&commitString, &specialCode); 
		if(specialCode.Get())
			_pUIPresenter->ShowNotifyText(&specialCode);
	}
	convertedString = commitString;
	//----------------- do TC to SC covert if required----------------------------------------------------------------------------------
	if(CConfig::GetDoHanConvert())
	{
		_pCompositionProcessorEngine->GetSCFromTC(&commitString, &convertedString);
	}
	//----------------- commit the selected string  ------------------------------------------------------------------------------------ 
	if(Global::imeMode == IME_MODE_ARRAY && !_IsUILessMode()  && !arrayUsingSPCode && CConfig::GetArrayForceSP() &&  ArraySPFound )
	{
		_HandleCancel(ec, pContext);
		DoBeep(BEEP_WARNING);
		return hr;
	}
	else
	{
		hr = _AddComposingAndChar(ec, pContext, &convertedString);
		if (FAILED(hr))	return hr;
		// Do not send _endcandidatelist (or handleComplete) here to avoid cand dissapear in win8 metro
		_HandleComplete(ec,pContext);
	}
	//-----------------do accociated phrase (make phrase)--------------------------------------------------------------------------------
	if (CConfig::GetMakePhrase())
	{
		_pCompositionProcessorEngine->GetCandidateStringInConverted(lastChar, &candidatePhraseList);


		// We have a candidate list if candidatePhraseList.Cnt is not 0
		// If we are showing reverse conversion, use UIPresenter

		if (candidatePhraseList.Count())
		{
			CStringRange emptyComposition;
			if (!_IsComposing())
				_StartComposition(pContext);  //StartCandidateList require a valid selection from a valid pComposition to determine the location to show the candidate window
			_AddComposingAndChar(ec, pContext, &emptyComposition.Set(L" ",1)); 

			_pUIPresenter->_ClearCandidateList();
			_pUIPresenter->_SetCandidateTextColor(CConfig::GetPhraseColor(), CConfig::GetItemBGColor());    // Text color is green
			_pUIPresenter->_SetCandidateSelectedTextColor(CConfig::GetSelectedColor(), CConfig::GetSelectedBGColor());    
			_pUIPresenter->_SetCandidateNumberColor(CConfig::GetNumberColor(), CConfig::GetItemBGColor());    
			_pUIPresenter->_SetCandidateFillColor(CConfig::GetItemBGColor());//(HBRUSH)(COLOR_WINDOW+1));    // Background color is window
			_pUIPresenter->_SetCandidateText(&candidatePhraseList, _pCompositionProcessorEngine->GetCandidateListIndexRange(),
				TRUE, _pCompositionProcessorEngine->GetCandidateWindowWidth());
			_pUIPresenter->_SetCandidateSelection(-1, FALSE); // set selected index to -1 if showing phrase candidates
			_candidateMode = CANDIDATE_PHRASE;
			_isCandidateWithWildcard = FALSE;	
			
		}
		else
		{   //cancel the composition if the phrase lookup return 0 results
			_HandleCancel(ec,pContext);
		}


	}
	else
		_DeleteCandidateList(TRUE, pContext); // endCanddiateUI if not doing associated phrase.
		
Exit:
    return hr;
}
Пример #27
0
BOOL CTextService::_IsKeyEaten(ITfContext *pContext, WPARAM wParam)
{
	if(_IsKeyboardDisabled())
	{
		return FALSE;
	}

	if(!_IsKeyboardOpen())
	{
		return FALSE;
	}

	if(_pCandidateList && _pCandidateList->_IsContextCandidateWindow(pContext))
	{
		return FALSE;
	}

	if(_IsComposing())
	{
		return TRUE;
	}

	SHORT vk_ctrl = GetKeyState(VK_CONTROL) & 0x8000;
	SHORT vk_kana = GetKeyState(VK_KANA) & 0x0001;

	WCHAR ch = _GetCh((BYTE)wParam);
	BYTE sf = _GetSf((BYTE)wParam, ch);

	//確定状態で処理する機能
	switch(inputmode)
	{
	case im_hiragana:
		switch(sf)
		{
		case SKK_CONV_POINT:
			return TRUE;
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}

	//無効
	if(_IsKeyVoid(ch, (BYTE)wParam))
	{
		return TRUE;
	}

	//処理しないCtrlキー
	if(vk_ctrl != 0)
	{
		return FALSE;
	}

	if(ch >= L'\x20')
	{
		return TRUE;
	}

	return FALSE;
}