249 lines
11 KiB
C++
249 lines
11 KiB
C++
// 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
|
|
|
|
#pragma once
|
|
|
|
#include "KeyHandlerEditSession.h"
|
|
#include "SampleIMEBaseStructure.h"
|
|
|
|
class CLangBarItemButton;
|
|
class CCandidateListUIPresenter;
|
|
class CCompositionProcessorEngine;
|
|
|
|
const DWORD WM_CheckGlobalCompartment = WM_USER;
|
|
LRESULT CALLBACK CSampleIME_WindowProc(HWND wndHandle, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
class CSampleIME : public ITfTextInputProcessorEx,
|
|
public ITfThreadMgrEventSink,
|
|
public ITfTextEditSink,
|
|
public ITfKeyEventSink,
|
|
public ITfCompositionSink,
|
|
public ITfDisplayAttributeProvider,
|
|
public ITfActiveLanguageProfileNotifySink,
|
|
public ITfThreadFocusSink,
|
|
public ITfFunctionProvider,
|
|
public ITfFnGetPreferredTouchKeyboardLayout
|
|
{
|
|
public:
|
|
CSampleIME();
|
|
~CSampleIME();
|
|
|
|
// IUnknown
|
|
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
// ITfTextInputProcessor
|
|
STDMETHODIMP Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) {
|
|
return ActivateEx(pThreadMgr, tfClientId, 0);
|
|
}
|
|
// ITfTextInputProcessorEx
|
|
STDMETHODIMP ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags);
|
|
STDMETHODIMP Deactivate();
|
|
|
|
// ITfThreadMgrEventSink
|
|
STDMETHODIMP OnInitDocumentMgr(_In_ ITfDocumentMgr *pDocMgr);
|
|
STDMETHODIMP OnUninitDocumentMgr(_In_ ITfDocumentMgr *pDocMgr);
|
|
STDMETHODIMP OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDocumentMgr *pDocMgrPrevFocus);
|
|
STDMETHODIMP OnPushContext(_In_ ITfContext *pContext);
|
|
STDMETHODIMP OnPopContext(_In_ ITfContext *pContext);
|
|
|
|
// ITfTextEditSink
|
|
STDMETHODIMP OnEndEdit(__RPC__in_opt ITfContext *pContext, TfEditCookie ecReadOnly, __RPC__in_opt ITfEditRecord *pEditRecord);
|
|
|
|
// ITfKeyEventSink
|
|
STDMETHODIMP OnSetFocus(BOOL fForeground);
|
|
STDMETHODIMP OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
|
|
STDMETHODIMP OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
|
|
STDMETHODIMP OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
|
|
STDMETHODIMP OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
|
|
STDMETHODIMP OnPreservedKey(ITfContext *pContext, REFGUID rguid, BOOL *pIsEaten);
|
|
|
|
// ITfCompositionSink
|
|
STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, _In_ ITfComposition *pComposition);
|
|
|
|
// ITfDisplayAttributeProvider
|
|
STDMETHODIMP EnumDisplayAttributeInfo(__RPC__deref_out_opt IEnumTfDisplayAttributeInfo **ppEnum);
|
|
STDMETHODIMP GetDisplayAttributeInfo(__RPC__in REFGUID guidInfo, __RPC__deref_out_opt ITfDisplayAttributeInfo **ppInfo);
|
|
|
|
// ITfActiveLanguageProfileNotifySink
|
|
STDMETHODIMP OnActivated(_In_ REFCLSID clsid, _In_ REFGUID guidProfile, _In_ BOOL isActivated);
|
|
|
|
// ITfThreadFocusSink
|
|
STDMETHODIMP OnSetThreadFocus();
|
|
STDMETHODIMP OnKillThreadFocus();
|
|
|
|
// ITfFunctionProvider
|
|
STDMETHODIMP GetType(__RPC__out GUID *pguid);
|
|
STDMETHODIMP GetDescription(__RPC__deref_out_opt BSTR *pbstrDesc);
|
|
STDMETHODIMP GetFunction(__RPC__in REFGUID rguid, __RPC__in REFIID riid, __RPC__deref_out_opt IUnknown **ppunk);
|
|
|
|
// ITfFunction
|
|
STDMETHODIMP GetDisplayName(_Out_ BSTR *pbstrDisplayName);
|
|
|
|
// ITfFnGetPreferredTouchKeyboardLayout, it is the Optimized layout feature.
|
|
STDMETHODIMP GetLayout(_Out_ TKBLayoutType *ptkblayoutType, _Out_ WORD *pwPreferredLayoutId);
|
|
|
|
// CClassFactory factory callback
|
|
static HRESULT CreateInstance(_In_ IUnknown *pUnkOuter, REFIID riid, _Outptr_ void **ppvObj);
|
|
|
|
// utility function for thread manager.
|
|
ITfThreadMgr* _GetThreadMgr() { return _pThreadMgr; }
|
|
TfClientId _GetClientId() { return _tfClientId; }
|
|
|
|
// functions for the composition object.
|
|
void _SetComposition(_In_ ITfComposition *pComposition);
|
|
void _TerminateComposition(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isCalledFromDeactivate = FALSE);
|
|
void _SaveCompositionContext(_In_ ITfContext *pContext);
|
|
|
|
// key event handlers for composition/candidate/phrase common objects.
|
|
HRESULT _HandleComplete(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
HRESULT _HandleCancel(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
|
|
// key event handlers for composition object.
|
|
HRESULT _HandleCompositionInput(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch);
|
|
HRESULT _HandleCompositionFinalize(TfEditCookie ec, _In_ ITfContext *pContext, BOOL fCandidateList);
|
|
HRESULT _HandleCompositionConvert(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isWildcardSearch);
|
|
HRESULT _HandleCompositionBackspace(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
HRESULT _HandleCompositionArrowKey(TfEditCookie ec, _In_ ITfContext *pContext, KEYSTROKE_FUNCTION keyFunction);
|
|
HRESULT _HandleCompositionPunctuation(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch);
|
|
HRESULT _HandleCompositionDoubleSingleByte(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch);
|
|
|
|
// key event handlers for candidate object.
|
|
HRESULT _HandleCandidateFinalize(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
HRESULT _HandleCandidateConvert(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
HRESULT _HandleCandidateArrowKey(TfEditCookie ec, _In_ ITfContext *pContext, _In_ KEYSTROKE_FUNCTION keyFunction);
|
|
HRESULT _HandleCandidateSelectByNumber(TfEditCookie ec, _In_ ITfContext *pContext, _In_ UINT uCode);
|
|
|
|
// key event handlers for phrase object.
|
|
HRESULT _HandlePhraseFinalize(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
HRESULT _HandlePhraseArrowKey(TfEditCookie ec, _In_ ITfContext *pContext, _In_ KEYSTROKE_FUNCTION keyFunction);
|
|
HRESULT _HandlePhraseSelectByNumber(TfEditCookie ec, _In_ ITfContext *pContext, _In_ UINT uCode);
|
|
|
|
BOOL _IsSecureMode(void) { return (_dwActivateFlags & TF_TMAE_SECUREMODE) ? TRUE : FALSE; }
|
|
BOOL _IsComLess(void) { return (_dwActivateFlags & TF_TMAE_COMLESS) ? TRUE : FALSE; }
|
|
BOOL _IsStoreAppMode(void) { return (_dwActivateFlags & TF_TMF_IMMERSIVEMODE) ? TRUE : FALSE; };
|
|
|
|
CCompositionProcessorEngine* GetCompositionProcessorEngine() { return (_pCompositionProcessorEngine); };
|
|
|
|
// comless helpers
|
|
static HRESULT CSampleIME::CreateInstance(REFCLSID rclsid, REFIID riid, _Outptr_result_maybenull_ LPVOID* ppv, _Out_opt_ HINSTANCE* phInst, BOOL isComLessMode);
|
|
static HRESULT CSampleIME::ComLessCreateInstance(REFGUID rclsid, REFIID riid, _Outptr_result_maybenull_ void **ppv, _Out_opt_ HINSTANCE *phInst);
|
|
static HRESULT CSampleIME::GetComModuleName(REFGUID rclsid, _Out_writes_(cchPath)WCHAR* wchPath, DWORD cchPath);
|
|
|
|
private:
|
|
// functions for the composition object.
|
|
HRESULT _HandleCompositionInputWorker(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext);
|
|
HRESULT _CreateAndStartCandidate(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext);
|
|
HRESULT _HandleCandidateWorker(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
|
|
void _StartComposition(_In_ ITfContext *pContext);
|
|
void _EndComposition(_In_opt_ ITfContext *pContext);
|
|
BOOL _IsComposing();
|
|
BOOL _IsKeyboardDisabled();
|
|
|
|
HRESULT _AddComposingAndChar(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString);
|
|
HRESULT _AddCharAndFinalize(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString);
|
|
|
|
BOOL _FindComposingRange(TfEditCookie ec, _In_ ITfContext *pContext, _In_ ITfRange *pSelection, _Outptr_result_maybenull_ ITfRange **ppRange);
|
|
HRESULT _SetInputString(TfEditCookie ec, _In_ ITfContext *pContext, _Out_opt_ ITfRange *pRange, _In_ CStringRange *pstrAddString, BOOL exist_composing);
|
|
HRESULT _InsertAtSelection(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString, _Outptr_ ITfRange **ppCompRange);
|
|
|
|
HRESULT _RemoveDummyCompositionForComposing(TfEditCookie ec, _In_ ITfComposition *pComposition);
|
|
|
|
// Invoke key handler edit session
|
|
HRESULT _InvokeKeyHandler(_In_ ITfContext *pContext, UINT code, WCHAR wch, DWORD flags, _KEYSTROKE_STATE keyState);
|
|
|
|
// function for the language property
|
|
BOOL _SetCompositionLanguage(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
|
|
// function for the display attribute
|
|
void _ClearCompositionDisplayAttributes(TfEditCookie ec, _In_ ITfContext *pContext);
|
|
BOOL _SetCompositionDisplayAttributes(TfEditCookie ec, _In_ ITfContext *pContext, TfGuidAtom gaDisplayAttribute);
|
|
BOOL _InitDisplayAttributeGuidAtom();
|
|
|
|
BOOL _InitThreadMgrEventSink();
|
|
void _UninitThreadMgrEventSink();
|
|
|
|
BOOL _InitTextEditSink(_In_ ITfDocumentMgr *pDocMgr);
|
|
|
|
void _UpdateLanguageBarOnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus);
|
|
|
|
BOOL _InitKeyEventSink();
|
|
void _UninitKeyEventSink();
|
|
|
|
BOOL _InitActiveLanguageProfileNotifySink();
|
|
void _UninitActiveLanguageProfileNotifySink();
|
|
|
|
BOOL _IsKeyEaten(_In_ ITfContext *pContext, UINT codeIn, _Out_ UINT *pCodeOut, _Out_writes_(1) WCHAR *pwch, _Out_opt_ _KEYSTROKE_STATE *pKeyState);
|
|
|
|
BOOL _IsRangeCovered(TfEditCookie ec, _In_ ITfRange *pRangeTest, _In_ ITfRange *pRangeCover);
|
|
VOID _DeleteCandidateList(BOOL fForce, _In_opt_ ITfContext *pContext);
|
|
|
|
WCHAR ConvertVKey(UINT code);
|
|
|
|
BOOL _InitThreadFocusSink();
|
|
void _UninitThreadFocusSink();
|
|
|
|
BOOL _InitFunctionProviderSink();
|
|
void _UninitFunctionProviderSink();
|
|
|
|
BOOL _AddTextProcessorEngine();
|
|
|
|
BOOL VerifySampleIMECLSID(_In_ REFCLSID clsid);
|
|
|
|
friend LRESULT CALLBACK CSampleIME_WindowProc(HWND wndHandle, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
private:
|
|
ITfThreadMgr* _pThreadMgr;
|
|
TfClientId _tfClientId;
|
|
DWORD _dwActivateFlags;
|
|
|
|
// The cookie of ThreadMgrEventSink
|
|
DWORD _threadMgrEventSinkCookie;
|
|
|
|
ITfContext* _pTextEditSinkContext;
|
|
DWORD _textEditSinkCookie;
|
|
|
|
// The cookie of ActiveLanguageProfileNotifySink
|
|
DWORD _activeLanguageProfileNotifySinkCookie;
|
|
|
|
// The cookie of ThreadFocusSink
|
|
DWORD _dwThreadFocusSinkCookie;
|
|
|
|
// Composition Processor Engine object.
|
|
CCompositionProcessorEngine* _pCompositionProcessorEngine;
|
|
|
|
// Language bar item object.
|
|
CLangBarItemButton* _pLangBarItem;
|
|
|
|
// the current composition object.
|
|
ITfComposition* _pComposition;
|
|
|
|
// guidatom for the display attibute.
|
|
TfGuidAtom _gaDisplayAttributeInput;
|
|
TfGuidAtom _gaDisplayAttributeConverted;
|
|
|
|
CANDIDATE_MODE _candidateMode;
|
|
CCandidateListUIPresenter *_pCandidateListUIPresenter;
|
|
BOOL _isCandidateWithWildcard : 1;
|
|
|
|
ITfDocumentMgr* _pDocMgrLastFocused;
|
|
|
|
ITfContext* _pContext;
|
|
|
|
ITfCompartment* _pSIPIMEOnOffCompartment;
|
|
DWORD _dwSIPIMEOnOffCompartmentSinkCookie;
|
|
|
|
HWND _msgWndHandle;
|
|
|
|
LONG _refCount;
|
|
|
|
// Support the search integration
|
|
ITfFnSearchCandidateProvider* _pITfFnSearchCandidateProvider;
|
|
};
|