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.
345 lines
7.2 KiB
345 lines
7.2 KiB
//
|
|
// candkey.cpp
|
|
//
|
|
|
|
#include "private.h"
|
|
#include "globals.h"
|
|
#include "mscandui.h"
|
|
#include "candkey.h"
|
|
#include "candui.h"
|
|
|
|
void DllAddRef(void);
|
|
void DllRelease(void);
|
|
|
|
/*============================================================================*/
|
|
/* */
|
|
/* C C A N D U I K E Y T A B L E */
|
|
/* */
|
|
/*============================================================================*/
|
|
|
|
/* C C A N D U I K E Y T A B L E */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
------------------------------------------------------------------------------*/
|
|
CCandUIKeyTable::CCandUIKeyTable( void )
|
|
{
|
|
m_cRef = 1;
|
|
|
|
m_nKeyData = 0;
|
|
m_pKeyData = NULL;
|
|
|
|
DllAddRef();
|
|
}
|
|
|
|
|
|
/* ~ C C A N D U I K E Y T A B L E */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
------------------------------------------------------------------------------*/
|
|
CCandUIKeyTable::~CCandUIKeyTable( void )
|
|
{
|
|
if (m_pKeyData != NULL) {
|
|
delete m_pKeyData;
|
|
}
|
|
|
|
DllRelease();
|
|
}
|
|
|
|
|
|
/* Q U E R Y I N T E R F A C E */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Query interface
|
|
(IUnknown method)
|
|
|
|
------------------------------------------------------------------------------*/
|
|
STDAPI CCandUIKeyTable::QueryInterface( REFIID riid, void **ppvObj )
|
|
{
|
|
if (ppvObj == NULL) {
|
|
return E_POINTER;
|
|
}
|
|
|
|
*ppvObj = NULL;
|
|
|
|
if (IsEqualIID( riid, IID_IUnknown ) || IsEqualIID( riid, IID_ITfCandUIKeyTable )) {
|
|
*ppvObj = SAFECAST( this, ITfCandUIKeyTable* );
|
|
}
|
|
|
|
if (*ppvObj == NULL) {
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/* A D D R E F */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Increment reference count
|
|
(IUnknown method)
|
|
|
|
------------------------------------------------------------------------------*/
|
|
STDAPI_(ULONG) CCandUIKeyTable::AddRef( void )
|
|
{
|
|
m_cRef++;
|
|
return m_cRef;
|
|
}
|
|
|
|
|
|
/* R E L E A S E */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Decrement reference count and release object
|
|
(IUnknown method)
|
|
|
|
------------------------------------------------------------------------------*/
|
|
STDAPI_(ULONG) CCandUIKeyTable::Release( void )
|
|
{
|
|
m_cRef--;
|
|
if (0 < m_cRef) {
|
|
return m_cRef;
|
|
}
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* G E T K E Y D A T A N U M */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Get count of key data
|
|
(ITfCandUIKeyTable method)
|
|
|
|
------------------------------------------------------------------------------*/
|
|
HRESULT CCandUIKeyTable::GetKeyDataNum( int *piNum )
|
|
{
|
|
if (piNum == NULL) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
*piNum = m_nKeyData;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/* G E T K E Y D A T A */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Get key data
|
|
(ITfCandUIKeyTable method)
|
|
|
|
------------------------------------------------------------------------------*/
|
|
HRESULT CCandUIKeyTable::GetKeyData( int iData, CANDUIKEYDATA *pData )
|
|
{
|
|
*pData = m_pKeyData[iData];
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/* S E T K E Y T A B L E */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
------------------------------------------------------------------------------*/
|
|
HRESULT CCandUIKeyTable::SetKeyTable( const CANDUIKEYDATA *pKeyData, int nKeyData )
|
|
{
|
|
Assert( 0 <= nKeyData );
|
|
|
|
if (m_pKeyData != NULL) {
|
|
delete m_pKeyData;
|
|
}
|
|
|
|
// copy data to buffer
|
|
|
|
m_nKeyData = nKeyData;
|
|
m_pKeyData = new CANDUIKEYDATA[ nKeyData ];
|
|
|
|
if (m_pKeyData)
|
|
memcpy( m_pKeyData, pKeyData, sizeof(CANDUIKEYDATA)*nKeyData );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/* S E T K E Y T A B L E */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
------------------------------------------------------------------------------*/
|
|
HRESULT CCandUIKeyTable::SetKeyTable( ITfCandUIKeyTable *pCandUIKeyTable )
|
|
{
|
|
HRESULT hr;
|
|
int i;
|
|
int nKeyData;
|
|
CANDUIKEYDATA *pKeyData;
|
|
|
|
Assert( pCandUIKeyTable != NULL );
|
|
|
|
if (m_pKeyData != NULL) {
|
|
delete m_pKeyData;
|
|
m_pKeyData = NULL;
|
|
m_nKeyData = 0;
|
|
}
|
|
|
|
// get number
|
|
|
|
hr = pCandUIKeyTable->GetKeyDataNum( &nKeyData );
|
|
if (hr != S_OK) {
|
|
return hr;
|
|
}
|
|
if (nKeyData <= 0) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
// create buffer
|
|
|
|
pKeyData = new CANDUIKEYDATA[ nKeyData ];
|
|
if (pKeyData == NULL) {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
for (i = 0; i < nKeyData; i++) {
|
|
hr = pCandUIKeyTable->GetKeyData( i, &pKeyData[i] );
|
|
if (hr != S_OK) {
|
|
delete pKeyData;
|
|
return E_FAIL;
|
|
}
|
|
}
|
|
|
|
//
|
|
|
|
m_pKeyData = pKeyData;
|
|
m_nKeyData = nKeyData;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/* C O M M A N D F R O M K E Y */
|
|
/*------------------------------------------------------------------------------
|
|
|
|
Get command from key
|
|
|
|
------------------------------------------------------------------------------*/
|
|
void CCandUIKeyTable::CommandFromKey( UINT uVKey, WCHAR wch, BYTE *pbKeyState, CANDUIUIDIRECTION uidir, CANDUICOMMAND *pcmd, UINT *pParam )
|
|
{
|
|
BOOL fShift;
|
|
BOOL fCtrl;
|
|
int i;
|
|
int iRotRelative;
|
|
|
|
Assert( pcmd != NULL );
|
|
Assert( pParam != NULL );
|
|
|
|
*pcmd = CANDUICMD_NONE;
|
|
*pParam = 0;
|
|
|
|
// get keystate
|
|
|
|
fShift = (pbKeyState[ VK_SHIFT ] & 0x80) != 0;
|
|
fCtrl = (pbKeyState[ VK_CONTROL ] & 0x80) != 0;
|
|
|
|
// calc rotation for relative direction key
|
|
|
|
switch (uidir) {
|
|
default:
|
|
case CANDUIDIR_TOPTOBOTTOM: {
|
|
iRotRelative = 0;
|
|
break;
|
|
}
|
|
|
|
case CANDUIDIR_RIGHTTOLEFT: {
|
|
iRotRelative = 1;
|
|
break;
|
|
}
|
|
|
|
case CANDUIDIR_BOTTOMTOTOP: {
|
|
iRotRelative = 2;
|
|
break;
|
|
}
|
|
|
|
case CANDUIDIR_LEFTTORIGHT: {
|
|
iRotRelative = 3;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// find the key from keymap table
|
|
|
|
for (i = 0; i < m_nKeyData; i++) {
|
|
BOOL fMatch = FALSE;
|
|
|
|
if (m_pKeyData[i].dwFlag == CANDUIKEY_CHAR) {
|
|
// check character code
|
|
|
|
fMatch = ((WCHAR)m_pKeyData[i].uiKey == wch);
|
|
}
|
|
else {
|
|
UINT uVKeyFixed;
|
|
|
|
// map directional key when it's relative
|
|
|
|
uVKeyFixed = m_pKeyData[i].uiKey;
|
|
if (m_pKeyData[i].dwFlag & CANDUIKEY_RELATIVEDIR) {
|
|
int iKey;
|
|
const UINT rguVKey[4] = {
|
|
VK_DOWN,
|
|
VK_LEFT,
|
|
VK_UP,
|
|
VK_RIGHT
|
|
};
|
|
|
|
// find key
|
|
|
|
for (iKey = 0; iKey < 4; iKey++) {
|
|
if (uVKeyFixed == rguVKey[iKey]) {
|
|
uVKeyFixed = rguVKey[ (iKey + iRotRelative) % 4 ];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// check keycode
|
|
|
|
fMatch = (uVKeyFixed == uVKey);
|
|
|
|
// check shift state
|
|
|
|
if (m_pKeyData[i].dwFlag & CANDUIKEY_SHIFT) {
|
|
fMatch &= fShift;
|
|
}
|
|
else if (m_pKeyData[i].dwFlag & CANDUIKEY_NOSHIFT) {
|
|
fMatch &= (!fShift);
|
|
}
|
|
|
|
// check ctrl state
|
|
|
|
if (m_pKeyData[i].dwFlag & CANDUIKEY_CTRL) {
|
|
fMatch &= fCtrl;
|
|
}
|
|
else if (m_pKeyData[i].dwFlag & CANDUIKEY_NOCTRL) {
|
|
fMatch &= (!fCtrl);
|
|
}
|
|
}
|
|
|
|
// match?
|
|
|
|
if (fMatch) {
|
|
*pcmd = m_pKeyData[i].cmd;
|
|
*pParam = m_pKeyData[i].uiParam;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|