|
|
//
// KORIMX.H : CKorIMX class declaration
//
// History:
// 15-NOV-1999 CSLim Created
#if !defined (__KORIMX_H__INCLUDED_)
#define __KORIMX_H__INCLUDED_
#include "globals.h"
#include "proputil.h"
#include "computil.h"
#include "dap.h"
#include "tes.h"
#include "kes.h"
#include "hauto.h"
#include "candlstx.h"
#include "mscandui.h"
#include "toolbar.h"
#include "editssn.h"
#include "immxutil.h"
#include "softkbd.h"
#include "skbdkor.h"
#include "pad.h"
#include "resource.h"
///////////////////////////////////////////////////////////////////////////////
// Class forward declarations
class CEditSession; class CICPriv; class CThreadMgrEventSink; class CFunctionProvider; class CHanja; class CCompositionInsertHelper;
///////////////////////////////////////////////////////////////////////////////
// Edit callback state values
#define ESCB_FINALIZECONVERSION 1
#define ESCB_COMPLETE 2
#define ESCB_INSERT_PAD_STRING 3
#define ESCB_KEYSTROKE 4
#define ESCB_TEXTEVENT 5
//#define ESCB_RANGEBROKEN 6
#define ESCB_CANDUI_CLOSECANDUI 6
#define ESCB_HANJA_CONV 7
#define ESCB_FINALIZERECONVERSION 8
#define ESCB_ONSELECTRECONVERSION 9
#define ESCB_ONCANCELRECONVERSION 10
#define ESCB_RECONV_QUERYRECONV 11
#define ESCB_RECONV_GETRECONV 12
#define ESCB_RECONV_SHOWCAND 13
#define ESCB_INIT_MODEBIAS 14
// Conversion modes(bit field for bit op)
#define TIP_ALPHANUMERIC_MODE 0
#define TIP_HANGUL_MODE 1
#define TIP_JUNJA_MODE 2
#define TIP_NULL_CONV_MODE 0x8000
//
// Text Direction
//
typedef enum { TEXTDIRECTION_TOPTOBOTTOM = 1, TEXTDIRECTION_RIGHTTOLEFT, TEXTDIRECTION_BOTTOMTOTOP, TEXTDIRECTION_LEFTTORIGHT, } TEXTDIRECTION;
///////////////////////////////////////////////////////////////////////////////
// CKorIMX class
class CKorIMX : public ITfTextInputProcessor, public ITfFnConfigure, public ITfThreadFocusSink, public ITfCompositionSink, public ITfCleanupContextSink, public ITfCleanupContextDurationSink, public ITfActiveLanguageProfileNotifySink, public ITfTextEditSink, public ITfEditTransactionSink, public CDisplayAttributeProvider { public: CKorIMX(); ~CKorIMX();
static HRESULT CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj); //
// IUnknown methods
//
virtual STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj); virtual STDMETHODIMP_(ULONG) AddRef(void); virtual STDMETHODIMP_(ULONG) Release(void);
private: long m_cRef;
public: //
// ITfX methods
//
STDMETHODIMP Activate(ITfThreadMgr *ptim, TfClientId tid); STDMETHODIMP Deactivate();
// ITfThreadFocusSink
STDMETHODIMP OnSetThreadFocus(); STDMETHODIMP OnKillThreadFocus();
// ITfCompositionSink
STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition);
// ITfCleanupContextDurationSink
STDMETHODIMP OnStartCleanupContext(); STDMETHODIMP OnEndCleanupContext();
// ITfCleanupContextSink
STDMETHODIMP OnCleanupContext(TfEditCookie ecWrite, ITfContext *pic);
// ITfActiveLanguageProfileNotifySink
STDMETHODIMP OnActivated(REFCLSID clsid, REFGUID guidProfile, BOOL fActivated);
// ITFFnConfigure
STDMETHODIMP GetDisplayName(BSTR *pbstrCand); STDMETHODIMP Show(HWND hwnd, LANGID langid, REFGUID rguidProfile);
// ITfTextEditSink
STDMETHODIMP OnEndEdit(ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord);
// ITfEditTransactionSink
STDMETHODIMP OnStartEditTransaction(ITfContext *pic); STDMETHODIMP OnEndEditTransaction(ITfContext *pic);
// Operations
public: // Get/Set On off status
BOOL IsOn(ITfContext *pic); void SetOnOff(ITfContext *pic, BOOL fOn);
static HRESULT _EditSessionCallback2(TfEditCookie ec, CEditSession2 *pes); HRESULT MakeResultString(TfEditCookie ec, ITfContext *pic, ITfRange *pRange);
// REVIEW: IC related functions
ITfContext* GetRootIC(ITfDocumentMgr* pDim = NULL); static BOOL IsDisabledIC(ITfContext *pic); static BOOL IsEmptyIC(ITfContext *pic); static BOOL IsCandidateIC(ITfContext *pic);
static HWND GetAppWnd(ITfContext *pic); BOOL IsPendingCleanup();
// Get AIMM or not?
static BOOL GetAIMM(ITfContext *pic);
// Get/Set conversion mode
DWORD GetConvMode(ITfContext *pic); DWORD SetConvMode(ITfContext *pic, DWORD dwConvMode);
// Retun current Automata object
CHangulAutomata* GetAutomata(ITfContext *pic);
// Cand UI functions
void OpenCandidateUI(TfEditCookie ec, ITfContext *pic, ITfRange *pRange, CCandidateListEx *pCandList); void CloseCandidateUI(ITfContext *pic); void CancelCandidate(TfEditCookie ec, ITfContext *pic);
// Soft Kbd functions
HRESULT InitializeSoftKbd(); BOOL IsSoftKbdEnabled() { return m_fSoftKbdEnabled; } void TerminateSoftKbd(); BOOL GetSoftKBDOnOff(); void SetSoftKBDOnOff(BOOL fOn); DWORD GetSoftKBDLayout(); void SetSoftKBDLayout(DWORD dwKbdLayout); HRESULT GetSoftKBDPosition(int *xWnd, int *yWnd); void SetSoftKBDPosition(int xWnd, int yWnd); SOFTLAYOUT* GetHangulSKbd() { return &m_KbdHangul; } // Data access functins
ITfDocumentMgr* GetDIM() { return m_pCurrentDim; } HRESULT GetFocusDIM(ITfDocumentMgr **ppdim); ITfThreadMgr* GetTIM() { return m_ptim; } TfClientId GetTID() { return m_tid; } ITfContext* GetIC(); CThreadMgrEventSink* GetTIMEventSink() { return m_ptimEventSink; } static CICPriv* GetInputContextPriv(ITfContext *pic); void OnFocusChange(ITfContext *pic, BOOL fActivate);
// Window object member access functions
HWND GetOwnerWnd() { return m_hOwnerWnd; }
// Get IImeIPoint
IImeIPoint1* GetIPoint (ITfContext *pic);
// KES_CODE_FOCUS set fForeground?
BOOL IsKeyFocus() { return m_fKeyFocus; }
// Get Pad Core
CPadCore* GetPadCore() { return m_pPadCore; }
// Update Toolbar button
void UpdateToolbar(DWORD dwUpdate) { m_pToolBar->Update(dwUpdate); } static LRESULT CALLBACK _OwnerWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
CFunctionProvider* GetFunctionProvider() { return m_pFuncPrv; }
// Cand UI helper
BOOL IsCandUIOpen() { return m_fCandUIOpen; }
// Get TLS
LIBTHREAD *_GetLibTLS() { return &m_libTLS; }
// Implementation
protected: // Helper functions
HRESULT SetInputString(TfEditCookie ec, ITfContext *pic, ITfRange *pRange, WCHAR *psz, LANGID langid); static LANGID GetLangID(); static WCHAR Banja2Junja(WCHAR bChar);
// Cand UI function
void GetCandidateFontInternal(TfEditCookie ec, ITfContext *pic, ITfRange *pRange, LOGFONTW *plf, LONG lFontPoint, BOOL fCandList);
//////////////////////////////////////////////////////////////////////////////
// Internal functions
private: // Callbacks
static HRESULT _KeyEventCallback(UINT uCode, ITfContext *pic, WPARAM wParam, LPARAM lParam, BOOL *pfEaten, void *pv); static HRESULT _PreKeyCallback(ITfContext *pic, REFGUID rguid, BOOL *pfEaten, void *pv); static HRESULT _DIMCallback(UINT uCode, ITfDocumentMgr *pdimNew, ITfDocumentMgr *pdimPrev, void *pv); static HRESULT _ICCallback(UINT uCode, ITfContext *pic, void *pv); static HRESULT _CompEventSinkCallback(void *pv, REFGUID rguid); static void _CleanupCompositionsCallback(TfEditCookie ecWrite, ITfRange *rangeComposition, void *pvPrivate);
void HAutoMata(TfEditCookie ec, ITfContext *pIIC, ITfRange *pIRange, LPBYTE lpbKeyState, WORD wVKey); BOOL _IsKeyEaten(ITfContext *pic, CKorIMX *pimx, WPARAM wParam, LPARAM lParam, const BYTE abKeyState[256]); HRESULT _Keystroke(TfEditCookie ec, ITfContext *pic, WPARAM wParam, LPARAM lParam, const BYTE abKeyState[256]);
// IC helpers
HRESULT _InitICPriv(ITfContext *pic); HRESULT _DeleteICPriv(ITfContext *pic);
// Hanja conversion
HRESULT DoHanjaConversion(TfEditCookie ec, ITfContext *pic, ITfRange *pRange); HRESULT Reconvert(ITfRange *pSelection);
// Composition
ITfComposition *GetIPComposition(ITfContext *pic); ITfComposition *CreateIPComposition(TfEditCookie ec, ITfContext *pic, ITfRange* pRangeComp); void SetIPComposition(ITfContext *pic, ITfComposition *pComposition); BOOL EndIPComposition(TfEditCookie ec, ITfContext *pic);
// Candidate list
CCandidateListEx *CreateCandidateList(ITfContext *pic, ITfRange *pRange, LPWSTR wchHangul); TEXTDIRECTION GetTextDirection(TfEditCookie ec, ITfContext *pic, ITfRange *pRange); CANDUIUIDIRECTION GetCandUIDirection(TfEditCookie ec, ITfContext *pic, ITfRange *pRange); void CloseCandidateUIProc(); void SelectCandidate(TfEditCookie ec, ITfContext *pic, INT idxCand, BOOL fFinalize); HMENU CreateCandidateMenu(ITfContext *pic); static HRESULT CandidateUICallBack(ITfContext *pic, ITfRange *pRange, CCandidateListEx *pCandList, CCandidateStringEx *pCand, TfCandidateResult imcr);
// Cand key
void SetCandidateKeyTable(ITfContext *pic, CANDUIUIDIRECTION dir); static BOOL IsCandKey(WPARAM wParam, const BYTE abKeyState[256]);
#if 0
// Range functions
void BackupRange(TfEditCookie ec, ITfContext *pic, ITfRange* pRange ); void RestoreRange(TfEditCookie ec, ITfContext *pic ); ITfRange* CreateIPRange(TfEditCookie ec, ITfContext *pic, ITfRange* pRangeOrg); void SetIPRange(TfEditCookie ec, ITfContext *pic, ITfRange* pRange); ITfRange* GetIPRange(TfEditCookie ec, ITfContext *pic); BOOL FlushIPRange(TfEditCookie ec, ITfContext *pic); #endif
// Modebias(ImmSetConversionStatus() API AIMM compatebility)
BOOL InitializeModeBias(TfEditCookie ec, ITfContext *pic); void CheckModeBias(ITfContext* pic); BOOL CheckModeBias(TfEditCookie ec, ITfContext *pic, ITfRange *pSelection);
// SoftKeyboard
//void OnActivatedSoftKbd(BOOl bActivated);
HRESULT ShowSoftKBDWindow(BOOL fShow); void SoftKbdOnThreadFocusChange(BOOL fSet); // Helpers
BOOL MySetText(TfEditCookie ec, ITfContext *pic, ITfRange *pRange, const WCHAR *psz, LONG cchText, LANGID langid, GUID *pattr);
BOOL IsKorIMX_GUID_ATOM(TfGuidAtom attr);
///////////////////////////////////////////////////////////////////////////////
// Internal data
private: ITfDocumentMgr *m_pCurrentDim; ITfThreadMgr *m_ptim; TfClientId m_tid; CThreadMgrEventSink *m_ptimEventSink; CKeyEventSink *m_pkes; HWND m_hOwnerWnd; BOOL m_fKeyFocus; CPadCore *m_pPadCore; CToolBar *m_pToolBar;
DWORD m_dwThreadFocusCookie; DWORD m_dwProfileNotifyCookie; BOOL m_fPendingCleanup;
CFunctionProvider* m_pFuncPrv;
// For overtyping
CCompositionInsertHelper *m_pInsertHelper;
// Candidate UI
ITfCandidateUI* m_pCandUI; BOOL m_fCandUIOpen;
// SoftKbd
BOOL m_fSoftKbdEnabled; ISoftKbd *m_pSoftKbd; SOFTLAYOUT m_KbdStandard; SOFTLAYOUT m_KbdHangul; CSoftKbdWindowEventSink *m_psftkbdwndes; DWORD m_dwSftKbdwndesCookie; BOOL m_fSoftKbdOnOffSave; // Tls for our helper library, we're apt threaded so tls can live in this object
LIBTHREAD m_libTLS;
BOOL m_fNoKorKbd; };
/*---------------------------------------------------------------------------
CKorIMX::IsPendingCleanup ---------------------------------------------------------------------------*/ inline BOOL CKorIMX::IsPendingCleanup() { return m_fPendingCleanup; }
/*---------------------------------------------------------------------------
CKorIMX::GetFocusDIM ---------------------------------------------------------------------------*/ inline HRESULT CKorIMX::GetFocusDIM(ITfDocumentMgr **ppdim) { Assert(ppdim); *ppdim = NULL; if (m_ptim != NULL) m_ptim->GetFocus(ppdim);
return *ppdim ? S_OK : E_FAIL; }
#include "icpriv.h"
/*---------------------------------------------------------------------------
CKorIMX::GetAutomata ---------------------------------------------------------------------------*/ inline CHangulAutomata* CKorIMX::GetAutomata(ITfContext *pic) { CICPriv* picp = GetInputContextPriv(pic); return (picp) ? GetInputContextPriv(pic)->GetAutomata() : NULL; }
/*---------------------------------------------------------------------------
CKorIMX::IsOn ---------------------------------------------------------------------------*/ inline BOOL CKorIMX::IsOn(ITfContext *pic) { DWORD dw = 0; if (pic == NULL) return fFalse;
GetCompartmentDWORD(GetTIM(), GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, &dw, fFalse);
return dw ? fTrue : fFalse; }
/*---------------------------------------------------------------------------
CKorIMX::GetConvMode ---------------------------------------------------------------------------*/ inline DWORD CKorIMX::GetConvMode(ITfContext *pic) { DWORD dw = 0;
if (pic == NULL) return TIP_ALPHANUMERIC_MODE;
GetCompartmentDWORD(GetTIM(), GUID_COMPARTMENT_KORIMX_CONVMODE, &dw, fFalse); return dw; }
/*---------------------------------------------------------------------------
CKorIMX::SetOnOff ---------------------------------------------------------------------------*/ inline void CKorIMX::SetOnOff(ITfContext *pic, BOOL fOn) { if (pic) SetCompartmentDWORD(m_tid, GetTIM(), GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, fOn ? 0x01 : 0x00, fFalse); }
/*---------------------------------------------------------------------------
CKorIMX::GetLangID ---------------------------------------------------------------------------*/ inline LANGID CKorIMX::GetLangID() { return MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT); }
/*---------------------------------------------------------------------------
CKorIMX::IsKorIMX_GUID_ATOM ---------------------------------------------------------------------------*/ inline BOOL CKorIMX::IsKorIMX_GUID_ATOM(TfGuidAtom attr) { if (IsEqualTFGUIDATOM(&m_libTLS, attr, GUID_ATTR_KORIMX_INPUT)) return fTrue;
return fFalse; }
/////////////////////////////////////////////////////////////////////////////
// S O F T K E Y B O A R D F U N C T I O N S
/////////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------------------
CKorIMX::GetSoftKBDOnOff ---------------------------------------------------------------------------*/ inline BOOL CKorIMX::GetSoftKBDOnOff() {
DWORD dw;
if (GetTIM() == NULL) return fFalse;
GetCompartmentDWORD(GetTIM(), GUID_COMPARTMENT_KOR_SOFTKBD_OPENCLOSE , &dw, fFalse); return dw ? TRUE : fFalse; }
/*---------------------------------------------------------------------------
CKorIMX::SetSoftKBDOnOff ---------------------------------------------------------------------------*/ inline void CKorIMX::SetSoftKBDOnOff(BOOL fOn) {
// check to see if the m_pSoftKbd and soft keyboard related members are initialized.
if (m_fSoftKbdEnabled == fFalse) InitializeSoftKbd();
if (m_pSoftKbd == NULL || GetTIM() == NULL) return;
if (fOn == GetSoftKBDOnOff()) return;
SetCompartmentDWORD(GetTID(), GetTIM(), GUID_COMPARTMENT_KOR_SOFTKBD_OPENCLOSE, fOn ? 0x01 : 0x00 , fFalse); }
/*---------------------------------------------------------------------------
CKorIMX::GetSoftKBDLayout ---------------------------------------------------------------------------*/ inline DWORD CKorIMX::GetSoftKBDLayout( ) {
DWORD dw;
if (m_pSoftKbd == NULL || GetTIM() == NULL) return NON_LAYOUT;
GetCompartmentDWORD(GetTIM(), GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, &dw, fFalse);
return dw;
}
/*---------------------------------------------------------------------------
CKorIMX::SetSoftKBDLayout ---------------------------------------------------------------------------*/ inline void CKorIMX::SetSoftKBDLayout(DWORD dwKbdLayout) { // check to see if the _SoftKbd and soft keyboard related members are initialized.
if (m_fSoftKbdEnabled == fFalse ) InitializeSoftKbd();
if ((m_pSoftKbd == NULL) || (GetTIM() == NULL)) return;
SetCompartmentDWORD(GetTID(), GetTIM(), GUID_COMPARTMENT_SOFTKBD_KBDLAYOUT, dwKbdLayout , fFalse); }
/*---------------------------------------------------------------------------
CKorIMX::GetSoftKBDPosition ---------------------------------------------------------------------------*/ inline HRESULT CKorIMX::GetSoftKBDPosition(int *xWnd, int *yWnd) { DWORD dwPos; HRESULT hr = S_OK;
if ((m_pSoftKbd == NULL) || (GetTIM() == NULL)) return E_FAIL;
if (!xWnd || !yWnd) return E_FAIL;
hr = GetCompartmentDWORD(GetTIM(), GUID_COMPARTMENT_SOFTKBD_WNDPOSITION, &dwPos, TRUE);
if (hr == S_OK) { *xWnd = dwPos & 0x0000ffff; *yWnd = (dwPos >> 16) & 0x0000ffff; hr = S_OK; } else { *xWnd = 0; *yWnd = 0; hr = E_FAIL; }
return hr; }
/*---------------------------------------------------------------------------
CKorIMX::SetSoftKBDPosition ---------------------------------------------------------------------------*/ inline void CKorIMX::SetSoftKBDPosition(int xWnd, int yWnd ) { DWORD dwPos; DWORD left, top;
if ((m_pSoftKbd == NULL) || (GetTIM() == NULL)) return;
if (xWnd < 0) left = 0; else left = (WORD)xWnd;
if (yWnd < 0) top = 0; else top = (WORD)yWnd;
dwPos = ((DWORD)top << 16) + left;
SetCompartmentDWORD(GetTID(), GetTIM(), GUID_COMPARTMENT_SOFTKBD_WNDPOSITION, dwPos, TRUE); }
/////////////////////////////////////////////////////////////////////////////
// H E L P E R F U N C T I O N S
/////////////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------------------
SetSelectionBlock
Wrapper for SetSelection that takes only a single range and sets default style values. ---------------------------------------------------------------------------*/ inline HRESULT SetSelectionBlock(TfEditCookie ec, ITfContext *pic, ITfRange *range) { TF_SELECTION sel;
sel.range = range; sel.style.ase = TF_AE_NONE; sel.style.fInterimChar = fTrue;
return pic->SetSelection(ec, 1, &sel); }
/*---------------------------------------------------------------------------
SetThis ---------------------------------------------------------------------------*/ inline void SetThis(HWND hWnd, LPARAM lParam) { SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)((CREATESTRUCT *)lParam)->lpCreateParams); }
/*---------------------------------------------------------------------------
GetThis ---------------------------------------------------------------------------*/ inline CKorIMX *GetThis(HWND hWnd) { CKorIMX *p = (CKorIMX *)GetWindowLongPtr(hWnd, GWLP_USERDATA); Assert(p != NULL); return p; }
#endif // __KORIMX_H__INCLUDED_
|