WindowsXP-SP1/windows/appcompat/compatui/accelcontainer.cpp
2020-09-30 16:53:49 +02:00

200 lines
5.4 KiB
C++

// AccelContainer.cpp: implementation of the CAccelContainer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AccelContainer.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
typedef struct _VKEYS {
LPCTSTR pKeyName;
WORD virtKey;
} VKEYS;
VKEYS vkeys[] = {
TEXT("BkSp"), VK_BACK,
TEXT("PgUp"), VK_PRIOR,
TEXT("PgDn"), VK_NEXT,
TEXT("End"), VK_END,
TEXT("Home"), VK_HOME,
TEXT("Left"), VK_LEFT,
TEXT("Up"), VK_UP,
TEXT("Right"),VK_RIGHT,
TEXT("Down"), VK_DOWN,
TEXT("Ins"), VK_INSERT,
TEXT("Del"), VK_DELETE,
TEXT("Mult"), VK_MULTIPLY,
TEXT("Add"), VK_ADD,
TEXT("Sub"), VK_SUBTRACT,
TEXT("DecPt"),VK_DECIMAL,
TEXT("Div"), VK_DIVIDE,
TEXT("F2"), VK_F2,
TEXT("F3"), VK_F3,
TEXT("F5"), VK_F5,
TEXT("F6"), VK_F6,
TEXT("F7"), VK_F7,
TEXT("F8"), VK_F8,
TEXT("F9"), VK_F9,
TEXT("F10"), VK_F10,
TEXT("F11"), VK_F11,
TEXT("F12"), VK_F12
};
wstring CAccelContainer::GetKeyFromAccel(const ACCEL& accel)
{
int i;
wstring strAccel((LPCTSTR)&accel.key, 1);
for (i = 0; i < sizeof(vkeys)/sizeof(vkeys[0]); ++i) {
if (vkeys[i].virtKey == accel.key) {
strAccel = vkeys[i].pKeyName;
break;
}
}
return strAccel;
}
BOOL CAccelContainer::IsAccelKey(LPMSG pMsg, WORD* pCmd)
{
ACCELVECTOR::iterator iter;
WORD fVirtKey = 0;
//
//
if (NULL == pMsg) {
fVirtKey |= (GetKeyState(VK_MENU) & 0x8000) ? FALT : 0;
fVirtKey |= (GetKeyState(VK_CONTROL) & 0x8000) ? FCONTROL : 0;
fVirtKey |= (GetKeyState(VK_SHIFT) & 0x8000) ? FSHIFT : 0;
fVirtKey |= FVIRTKEY;
for (iter = m_Accel.begin(); iter != m_Accel.end(); ++iter) {
const ACCEL& accl = *iter;
if (GetKeyState(accl.key) & 0x8000) {
//
// pressed! see if we have a match
//
if (fVirtKey == accl.fVirt) {
//
// we do have a match
//
if (pCmd) {
*pCmd = accl.cmd;
}
return TRUE;
}
}
}
} else {
// one of the nasty messages ?
if (pMsg->message == WM_SYSKEYDOWN || pMsg->message == WM_SYSKEYUP) {
fVirtKey = (pMsg->lParam & 0x20000000) ? FALT : 0;
fVirtKey |= FVIRTKEY; // always a virtkey code
for (iter = m_Accel.begin(); iter != m_Accel.end(); ++iter) {
const ACCEL& accl = *iter;
if (pMsg->wParam == accl.key) {
//
// pressed! see if we have a match
//
if (fVirtKey == accl.fVirt) {
//
// we do have a match
//
if (pCmd) {
*pCmd = accl.cmd;
}
return TRUE;
}
}
}
}
}
return FALSE;
}
VOID CAccelContainer::ParseAccelString(LPCTSTR lpszStr, WORD wCmd)
{
LPCTSTR pch = lpszStr;
LPCTSTR pchEnd, pchb;
ACCEL accl;
//
// nuke all
//
while (*pch) {
//
// skip whitespace
//
pch += _tcsspn(pch, TEXT(" \t"));
//
// see what kind of key this is
//
if (*pch == TEXT('{')) {
// some special key
++pch;
pch += _tcsspn(pch, TEXT(" \t"));
int i;
for (i = 0; i < sizeof(vkeys)/sizeof(vkeys[0]); ++i) {
int nLen = _tcslen(vkeys[i].pKeyName);
if (!_tcsnicmp(pch, vkeys[i].pKeyName, nLen)) {
// aha -- we have a match
//
accl.cmd = wCmd;
accl.fVirt = FALT|FVIRTKEY;
accl.key = vkeys[i].virtKey;
m_Accel.push_back(accl);
pch += nLen;
pch += _tcsspn(pch, TEXT(" \t"));
break;
}
}
pchEnd = _tcschr(pch, '}');
pchb = _tcschr(pch, '{');
if (pchEnd != NULL && (pchb == NULL || pchEnd < pchb)) {
pch = pchEnd + 1; // one past the bracket
}
// what if we have not succeeded - and no closing bracket ?
// we skip the bracket and go ahead as character
} else if (_istalnum(*pch)) { // normal key
TCHAR ch = _totupper(*pch);
accl.cmd = wCmd;
accl.fVirt = FALT|FVIRTKEY;
accl.key = ch;
m_Accel.push_back(accl);
++pch;
} else {
++pch; // skip the char, we can't recognize it
}
}
}