300 lines
8.4 KiB
C++
300 lines
8.4 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) 2003 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// KeyEventSink.cpp
|
|
//
|
|
// ITfKeyEventSink implementation.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Globals.h"
|
|
#include "TextService.h"
|
|
#include "CandidateList.h"
|
|
|
|
//
|
|
// GUID for the preserved keys.
|
|
//
|
|
/* 6a0bde41-6adf-11d7-a6ea-00065b84435c */
|
|
static const GUID GUID_PRESERVEDKEY_ONOFF = {
|
|
0x6a0bde41,
|
|
0x6adf,
|
|
0x11d7,
|
|
{0xa6, 0xea, 0x00, 0x06, 0x5b, 0x84, 0x43, 0x5c}
|
|
};
|
|
|
|
/* 6a0bde42-6adf-11d7-a6ea-00065b84435c */
|
|
static const GUID GUID_PRESERVEDKEY_F6 = {
|
|
0x6a0bde42,
|
|
0x6adf,
|
|
0x11d7,
|
|
{0xa6, 0xea, 0x00, 0x06, 0x5b, 0x84, 0x43, 0x5c}
|
|
};
|
|
|
|
|
|
//
|
|
// the preserved keys declaration
|
|
//
|
|
// VK_KANJI is the virtual key for Kanji key, which is available in 106
|
|
// Japanese keyboard.
|
|
//
|
|
static const TF_PRESERVEDKEY c_pkeyOnOff0 = { 0xC0, TF_MOD_ALT };
|
|
static const TF_PRESERVEDKEY c_pkeyOnOff1 = { VK_KANJI, TF_MOD_IGNORE_ALL_MODIFIER };
|
|
static const TF_PRESERVEDKEY c_pkeyF6 = { VK_F6, TF_MOD_ON_KEYUP };
|
|
|
|
//
|
|
// the description for the preserved keys
|
|
//
|
|
static const WCHAR c_szPKeyOnOff[] = L"OnOff";
|
|
static const WCHAR c_szPKeyF6[] = L"Function 6";
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _IsKeyEaten
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnSetFocus
|
|
//
|
|
// Called by the system whenever this service gets the keystroke device focus.
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CTextService::OnSetFocus(BOOL fForeground)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnTestKeyDown
|
|
//
|
|
// Called by the system to query this service wants a potential keystroke.
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CTextService::OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
|
|
{
|
|
*pfEaten = _IsKeyEaten(pContext, wParam);
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnKeyDown
|
|
//
|
|
// Called by the system to offer this service a keystroke. If *pfEaten == TRUE
|
|
// on exit, the application will not handle the keystroke.
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CTextService::OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
|
|
{
|
|
*pfEaten = _IsKeyEaten(pContext, wParam);
|
|
|
|
if (*pfEaten)
|
|
{
|
|
_InvokeKeyHandler(pContext, wParam, lParam);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnTestKeyUp
|
|
//
|
|
// Called by the system to query this service wants a potential keystroke.
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CTextService::OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
|
|
{
|
|
*pfEaten = _IsKeyEaten(pContext, wParam);
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnKeyUp
|
|
//
|
|
// Called by the system to offer this service a keystroke. If *pfEaten == TRUE
|
|
// on exit, the application will not handle the keystroke.
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CTextService::OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
|
|
{
|
|
*pfEaten = _IsKeyEaten(pContext, wParam);
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnPreservedKey
|
|
//
|
|
// Called when a hotkey (registered by us, or by the system) is typed.
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CTextService::OnPreservedKey(ITfContext *pContext, REFGUID rguid, BOOL *pfEaten)
|
|
{
|
|
|
|
if (IsEqualGUID(rguid, GUID_PRESERVEDKEY_ONOFF))
|
|
{
|
|
BOOL fOpen = _IsKeyboardOpen();
|
|
_SetKeyboardOpen(fOpen ? FALSE : TRUE);
|
|
*pfEaten = TRUE;
|
|
}
|
|
else
|
|
{
|
|
*pfEaten = FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _InitKeyEventSink
|
|
//
|
|
// Advise a keystroke sink.
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTextService::_InitKeyEventSink()
|
|
{
|
|
ITfKeystrokeMgr *pKeystrokeMgr;
|
|
HRESULT hr;
|
|
|
|
if (_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr) != S_OK)
|
|
return FALSE;
|
|
|
|
hr = pKeystrokeMgr->AdviseKeyEventSink(_tfClientId, (ITfKeyEventSink *)this, TRUE);
|
|
|
|
pKeystrokeMgr->Release();
|
|
|
|
return (hr == S_OK);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _UninitKeyEventSink
|
|
//
|
|
// Unadvise a keystroke sink. Assumes we have advised one already.
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTextService::_UninitKeyEventSink()
|
|
{
|
|
ITfKeystrokeMgr *pKeystrokeMgr;
|
|
|
|
if (_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr) != S_OK)
|
|
return;
|
|
|
|
pKeystrokeMgr->UnadviseKeyEventSink(_tfClientId);
|
|
|
|
pKeystrokeMgr->Release();
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _InitPreservedKey
|
|
//
|
|
// Register a hot key.
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTextService::_InitPreservedKey()
|
|
{
|
|
ITfKeystrokeMgr *pKeystrokeMgr;
|
|
HRESULT hr;
|
|
|
|
if (_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr) != S_OK)
|
|
return FALSE;
|
|
|
|
// register Alt+~ key
|
|
hr = pKeystrokeMgr->PreserveKey(_tfClientId,
|
|
GUID_PRESERVEDKEY_ONOFF,
|
|
&c_pkeyOnOff0,
|
|
c_szPKeyOnOff,
|
|
lstrlen(c_szPKeyOnOff));
|
|
|
|
// register KANJI key
|
|
hr = pKeystrokeMgr->PreserveKey(_tfClientId,
|
|
GUID_PRESERVEDKEY_ONOFF,
|
|
&c_pkeyOnOff1,
|
|
c_szPKeyOnOff,
|
|
lstrlen(c_szPKeyOnOff));
|
|
|
|
// register F6 key
|
|
hr = pKeystrokeMgr->PreserveKey(_tfClientId,
|
|
GUID_PRESERVEDKEY_F6,
|
|
&c_pkeyF6,
|
|
c_szPKeyF6,
|
|
lstrlen(c_szPKeyF6));
|
|
|
|
pKeystrokeMgr->Release();
|
|
|
|
return (hr == S_OK);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _UninitPreservedKey
|
|
//
|
|
// Uninit a hot key.
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTextService::_UninitPreservedKey()
|
|
{
|
|
ITfKeystrokeMgr *pKeystrokeMgr;
|
|
|
|
if (_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr) != S_OK)
|
|
return;
|
|
|
|
pKeystrokeMgr->UnpreserveKey(GUID_PRESERVEDKEY_ONOFF, &c_pkeyOnOff0);
|
|
pKeystrokeMgr->UnpreserveKey(GUID_PRESERVEDKEY_ONOFF, &c_pkeyOnOff1);
|
|
pKeystrokeMgr->UnpreserveKey(GUID_PRESERVEDKEY_F6, &c_pkeyF6);
|
|
|
|
pKeystrokeMgr->Release();
|
|
}
|
|
|