// 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; };