Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

288 lines
8.0 KiB

//
// keys.cpp
//
// ITfKeyEventSink implementation.
//
#include "globals.h"
#include "case.h"
#include "editsess.h"
class CKeystrokeEditSession : public CEditSessionBase
{
public:
CKeystrokeEditSession(ITfContext *pContext, WPARAM wParam) : CEditSessionBase(pContext)
{
_wParam = wParam;
}
// ITfEditSession
STDMETHODIMP DoEditSession(TfEditCookie ec);
private:
WPARAM _wParam;
};
/* 5d6d1b1e-64f2-47cd-9fe1-4e032c2dae77 */
static const GUID GUID_PRESERVEDKEY_FLIPCASE = { 0x5d6d1b1e, 0x64f2, 0x47cd, {0x9f, 0xe1, 0x4e, 0x03, 0x2c, 0x2d, 0xae, 0x77} };
// arbitrary hotkey: ctl-f
static const TF_PRESERVEDKEY c_FlipCaseKey = { 'F', TF_MOD_CONTROL };
//+---------------------------------------------------------------------------
//
// IsKeyEaten
//
//----------------------------------------------------------------------------
inline BOOL IsKeyEaten(BOOL fFlipKeys, WPARAM wParam)
{
// we're only interested in VK_A - VK_Z, when the "Flip Keys" menu option
// is on
return fFlipKeys && (wParam >= 'A') && (wParam <= 'Z');
}
//+---------------------------------------------------------------------------
//
// _Menu_FlipKeys
//
// Advise or unadvise a keystroke sink.
//----------------------------------------------------------------------------
/* static */
void CCaseTextService::_Menu_FlipKeys(CCaseTextService *_this)
{
_this->_fFlipKeys = !_this->_fFlipKeys;
}
//+---------------------------------------------------------------------------
//
// _InitKeystrokeSink
//
// Advise a keystroke sink.
//----------------------------------------------------------------------------
BOOL CCaseTextService::_InitKeystrokeSink()
{
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);
}
//+---------------------------------------------------------------------------
//
// _UninitKeystrokeSink
//
// Unadvise a keystroke sink. Assumes we have advised one already.
//----------------------------------------------------------------------------
void CCaseTextService::_UninitKeystrokeSink()
{
ITfKeystrokeMgr *pKeystrokeMgr;
if (_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr) != S_OK)
return;
pKeystrokeMgr->UnadviseKeyEventSink(_tfClientId);
pKeystrokeMgr->Release();
}
//+---------------------------------------------------------------------------
//
// _InitPreservedKey
//
// Register a hot key.
//----------------------------------------------------------------------------
BOOL CCaseTextService::_InitPreservedKey()
{
ITfKeystrokeMgr *pKeystrokeMgr;
HRESULT hr;
if (_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr) != S_OK)
return FALSE;
hr = pKeystrokeMgr->PreserveKey(_tfClientId, GUID_PRESERVEDKEY_FLIPCASE,
&c_FlipCaseKey, L"Toggle Case",
wcslen(L"Toggle Case"));
pKeystrokeMgr->Release();
return (hr == S_OK);
}
//+---------------------------------------------------------------------------
//
// _UninitPreservedKey
//
// Uninit a hot key.
//----------------------------------------------------------------------------
void CCaseTextService::_UninitPreservedKey()
{
ITfKeystrokeMgr *pKeystrokeMgr;
if (_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr) != S_OK)
return;
pKeystrokeMgr->UnpreserveKey(GUID_PRESERVEDKEY_FLIPCASE, &c_FlipCaseKey);
pKeystrokeMgr->Release();
}
//+---------------------------------------------------------------------------
//
// OnSetFocus
//
// Called by the system whenever this service gets the keystroke device focus.
//----------------------------------------------------------------------------
STDAPI CCaseTextService::OnSetFocus(BOOL fForeground)
{
return S_OK;
}
//+---------------------------------------------------------------------------
//
// OnTestKeyDown
//
// Called by the system to query this service wants a potential keystroke.
//----------------------------------------------------------------------------
STDAPI CCaseTextService::OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
*pfEaten = IsKeyEaten(_fFlipKeys, 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 CCaseTextService::OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
CKeystrokeEditSession *pEditSession;
HRESULT hr = S_OK;
*pfEaten = IsKeyEaten(_fFlipKeys, wParam);
if (*pfEaten)
{
// we'll insert a char ourselves in place of this keystroke
if ((pEditSession = new CKeystrokeEditSession(pContext, wParam)) == NULL)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// we need a lock to do our work
// nb: this method is one of the few places where it is legal to use
// the TF_ES_SYNC flag
if (pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hr) != S_OK)
{
hr = E_FAIL;
}
pEditSession->Release();
}
Exit:
if (hr != S_OK)
{
*pfEaten = FALSE;
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// DoEditSession
//
//----------------------------------------------------------------------------
STDAPI CKeystrokeEditSession::DoEditSession(TfEditCookie ec)
{
WCHAR wc;
// we want to toggle the english case of the keystroke
// nb: this is quick-and-dirty code, not intended to demonstrate the
// correct way to flip capitalization!
if (GetKeyState(VK_SHIFT) & 0x8000)
{
// shift-key, make it lowercase
wc = (WCHAR)(_wParam | 32);
}
else
{
// else make it capital
wc = (WCHAR)_wParam;
}
InsertTextAtSelection(ec, _pContext, &wc, 1);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// OnTestKeyUp
//
// Called by the system to query this service wants a potential keystroke.
//----------------------------------------------------------------------------
STDAPI CCaseTextService::OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
*pfEaten = IsKeyEaten(_fFlipKeys, 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 CCaseTextService::OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten)
{
*pfEaten = IsKeyEaten(_fFlipKeys, wParam);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// OnPreservedKey
//
// Called when a hotkey (registered by us, or by the system) is typed.
//----------------------------------------------------------------------------
STDAPI CCaseTextService::OnPreservedKey(ITfContext *pContext, REFGUID rguid, BOOL *pfEaten)
{
if (IsEqualGUID(rguid, GUID_PRESERVEDKEY_FLIPCASE))
{
_Menu_FlipDoc(this);
*pfEaten = TRUE;
}
else
{
*pfEaten = FALSE;
}
return S_OK;
}