[Windows] Address review comments, document, and tidy up constants

This commit is contained in:
Marc Durdin 2018-10-03 07:01:34 +10:00
parent eff9f834de
commit d2331680b2
10 changed files with 78 additions and 50 deletions

View file

@ -1043,6 +1043,6 @@ BOOL ShouldAttachToProcess()
void PostDummyKeyEvent() { // I3301 - Handle I3250 regression with inadvertent menu activation with Alt keys // I3534 // I4844
keybd_event(_VK_PREFIX, 0xFF, 0, 0); // I3250 - is this unnecessary?
keybd_event(_VK_PREFIX, 0xFF, KEYEVENTF_KEYUP, 0); // I3250 - is this unnecessary?
keybd_event(_VK_PREFIX, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0); // I3250 - is this unnecessary?
keybd_event(_VK_PREFIX, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0); // I3250 - is this unnecessary?
}

View file

@ -125,12 +125,12 @@ extern "C" __declspec(dllexport) BOOL WINAPI TIPProcessKey(WPARAM wParam, LPARAM
SendDebugMessageFormat(0, sdmAIDefault, 0, "TIPProcessKey: Enter VirtualKey=%s lParam=%x IsUp=%d Extended=%d Updateable=%d Preserved=%d", Debug_VirtualKey((WORD) wParam), lParam, isUp, extended, Updateable, Preserved);
if(_td->LastKey == wParam && (scan == 0 || scan == 0xFE)) { // I4642
if(_td->LastKey == wParam && (scan == 0 || scan == SCAN_FLAG_SERIALIZED_USER_KEY_EVENT)) { // I4642
scan = _td->LastScanCode;
SendDebugMessageFormat(0, sdmAIDefault, 0, "TIPProcessKey: Scan code was zero so using cached scan code %x", scan);
SendDebugMessageFormat(0, sdmAIDefault, 0, "TIPProcessKey: Scan code was zero or 0xFE so using cached scan code %x", scan);
}
if(scan == 0xFF) { // I4370
if(scan == SCAN_FLAG_KEYMAN_KEY_EVENT) { // I4370
SendDebugMessageFormat(0, sdmAIDefault, 0, "TIPProcessKey: Virtual Key was generated by Keyman [Scan=0xFF]");
return FALSE;
}

View file

@ -215,7 +215,7 @@ BOOL AIWin2000Unicode::PostKeys()
pInputs[i].type = INPUT_KEYBOARD;
pInputs[i].ki.wVk = (WORD)Queue[n].dwData & 0xFF; // I3242 - noted as unclean but was not cause of the issue // I3438 // I3527
pInputs[i].ki.wScan = 0xFF;
pInputs[i].ki.wScan = SCAN_FLAG_KEYMAN_KEY_EVENT;
pInputs[i].ki.dwFlags = ((Queue[n].dwData & QVK_EXTENDED) ? KEYEVENTF_EXTENDEDKEY : 0); // I3438
pInputs[i].ki.time = 0;
@ -242,7 +242,7 @@ BOOL AIWin2000Unicode::PostKeys()
{
pInputs[i].type = INPUT_KEYBOARD;
pInputs[i].ki.wVk = (WORD) Queue[n].dwData & 0xFF; // I3242 - noted as unclean but was not cause of the issue // I3438 // I3527
pInputs[i].ki.wScan = 0xFF;
pInputs[i].ki.wScan = SCAN_FLAG_KEYMAN_KEY_EVENT;
pInputs[i].ki.dwFlags = KEYEVENTF_KEYUP | ((Queue[n].dwData & QVK_EXTENDED) ? KEYEVENTF_EXTENDEDKEY : 0); // I3438
pInputs[i].ki.time = 0;
pInputs[i++].ki.dwExtraInfo = 0; //KEYEVENT_EXTRAINFO_KEYMAN; // I4370 // I4378
@ -281,14 +281,14 @@ BOOL AIWin2000Unicode::PostKeys()
pInputs[i].type = INPUT_KEYBOARD;
pInputs[i].ki.wVk = VK_BACK;
pInputs[i].ki.wScan = 0xFF;
pInputs[i].ki.wScan = SCAN_FLAG_KEYMAN_KEY_EVENT;
pInputs[i].ki.dwFlags = ((Queue[n].dwData & 0x0100) ? KEYEVENTF_EXTENDEDKEY : 0);
pInputs[i].ki.time = 0;
pInputs[i++].ki.dwExtraInfo = 0; //KEYEVENT_EXTRAINFO_KEYMAN; // I4370 // I4378
pInputs[i].type = INPUT_KEYBOARD;
pInputs[i].ki.wVk = VK_BACK;
pInputs[i].ki.wScan = 0xFF;
pInputs[i].ki.wScan = SCAN_FLAG_KEYMAN_KEY_EVENT;
pInputs[i].ki.dwFlags = KEYEVENTF_KEYUP | ((Queue[n].dwData & 0x0100) ? KEYEVENTF_EXTENDEDKEY : 0);
pInputs[i].ki.time = 0;
pInputs[i++].ki.dwExtraInfo = 0; //KEYEVENT_EXTRAINFO_KEYMAN; // I4370 // I4378

View file

@ -65,16 +65,16 @@ void KeyCapsLockPress(BOOL FIsUp) // I3284 - void // I3529
{
if(FIsUp && !(GetKeyState(VK_CAPITAL) & 1)) // I267 - 24/11/2006 invert GetKeyState test
{
keybd_event(VK_CAPITAL, 0xFF, 0, 0);
keybd_event(VK_CAPITAL, 0xFF, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0);
keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0);
}
}
else if(_td->lpActiveKeyboard->Keyboard->dwFlags & KF_CAPSALWAYSOFF)
{
if(!FIsUp && (GetKeyState(VK_CAPITAL) & 1))
{ // I267 - 24/11/2006 invert GetKeyState test
keybd_event(VK_CAPITAL, 0xFF, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CAPITAL, 0xFF, 0, 0);
keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0);
}
}
}
@ -92,8 +92,8 @@ void KeyShiftPress(BOOL FIsUp) // I3284 - void // I3529
{
if(!FIsUp)
{
keybd_event(VK_CAPITAL, 0xFF, 0, 0);
keybd_event(VK_CAPITAL, 0xFF, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0);
keybd_event(VK_CAPITAL, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0);
}
}
}

View file

@ -250,7 +250,7 @@ extern UINT
wm_keymanim_close,
wm_keymanim_contextchanged,
wm_test_keyman_functioning,
wm_keyman_ignore;
wm_keyman_ignore; // used to mask out messages that we don't want the target app to process, e.g. key events
extern BOOL
flag_ShouldSerializeInput,

View file

@ -76,8 +76,9 @@
UINT
//TODO: consolidate these messages -- they are probably not all required now
wm_keyman = 0, // user message - ignore msg // I3594
wm_keyman_ignore = 0,
wm_keyman_ignore = 0, // used to mask out messages that we don't want the target app to process, e.g. key events
wm_kmdebug = 0, // " " " " - debugging
wm_kmmessage = 0, // message to Keyman window // I4412

View file

@ -107,31 +107,22 @@ void do_keybd_event(LPINPUT pInputs, int *n, BYTE vk, BYTE scan, DWORD flags, UL
*/
void keybd_sendprefix(LPINPUT pInputs, int *n)
{
SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_sendshift: sending prefix down+up");
do_keybd_event(pInputs, n, _VK_PREFIX, 0xFF, 0, 0); // I4548 // I4844
do_keybd_event(pInputs, n, _VK_PREFIX, 0xFF, KEYEVENTF_KEYUP, 0); // I4548 // I4844
}
void keybd_sendshift(LPINPUT pInputs, int *n, BYTE vkey, BOOL isDown) {
SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_sendshift: sending key%s - vkey=%s", isDown ? "down" : "up", Debug_VirtualKey(vkey));
do_keybd_event(pInputs, n, vkey, 0xFF, isDown ? 0 : KEYEVENTF_KEYUP, 0); // I4548
SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_sendprefix: sending prefix down+up");
do_keybd_event(pInputs, n, _VK_PREFIX, SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0); // I4548 // I4844
do_keybd_event(pInputs, n, _VK_PREFIX, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0); // I4548 // I4844
}
/**
keybd_shift evaluates the current keyboard modifier state and queues key events in order to
initially set modifiers to "up" and, after the output key events are queued, resets the modifiers
to their initial state.
keybd_shift_release records the current keyboard state and then releases any modifier
keys. If a modifier key must be released, it first sends a dummy prefix key to prevent
isolated modifier key actions such as Alt opening up a menu.
Parameters: pInputs array of INPUT structures which we will fill with our key events.
n pointer to current index into pInput, which we increment for each key
n pointer to current index into pInput, which we increment for each key
event we add
FReset are we clearing or resetting the modifier state?
kbd pointer to keyboard state (256 byte array)
There must be enough space in pInputs to contain 6 x up + 6 x down + 2 prefix-down + 2 prefix-up event = 16 events,
to support both the clear and reset calls.
kbd pointer to keyboard state (256 byte array), in which we will store
the initial modifier state for later restoration by keybd_shift_reset
*/
void keybd_shift_release(LPINPUT pInputs, int *n, LPBYTE kbd) {
const BYTE modifiers[6] = { VK_LMENU, VK_RMENU, VK_LCONTROL, VK_RCONTROL, VK_LSHIFT, VK_RSHIFT };
BOOL hasSentPrefix = FALSE;
@ -144,18 +135,31 @@ void keybd_shift_release(LPINPUT pInputs, int *n, LPBYTE kbd) {
keybd_sendprefix(pInputs, n);
hasSentPrefix = TRUE;
}
keybd_sendshift(pInputs, n, modifiers[i], FALSE);
SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_shift_release: sending keyup vkey=%s", Debug_VirtualKey(modifiers[i]));
do_keybd_event(pInputs, n, modifiers[i], SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0);
}
}
}
/**
keybd_shift_reset returns the modifiers to their original pressed state and, if any modifier
key presses are emitted, emits also a dummy 'prefix' keystroke in order to prevent default
modifier actions such as Alt opening up a menu.
Parameters: pInputs array of INPUT structures which we will fill with our key events.
n pointer to current index into pInput, which we increment for each key
event we add
kbd pointer to keyboard state (256 byte array), previously set by
keybd_shift_release
*/
void keybd_shift_reset(LPINPUT pInputs, int *n, LPBYTE kbd) {
const BYTE modifiers[6] = { VK_LMENU, VK_RMENU, VK_LCONTROL, VK_RCONTROL, VK_LSHIFT, VK_RSHIFT };
BOOL needsPrefix = FALSE;
for (int i = 0; i < _countof(modifiers); i++) {
if (kbd[modifiers[i]] & 0x80) {
keybd_sendshift(pInputs, n, modifiers[i], TRUE);
SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_shift_reset: sending keydown vkey=%s", Debug_VirtualKey(modifiers[i]));
do_keybd_event(pInputs, n, modifiers[i], SCAN_FLAG_KEYMAN_KEY_EVENT, 0, 0);
needsPrefix = TRUE;
}
}
@ -165,6 +169,21 @@ void keybd_shift_reset(LPINPUT pInputs, int *n, LPBYTE kbd) {
}
}
/**
keybd_shift evaluates the current keyboard modifier state and queues key events in order to
initially set modifiers to "up" and, after the output key events are queued, resets the modifiers
to their initial state.
Parameters: pInputs array of INPUT structures which we will fill with our key events.
n pointer to current index into pInput, which we increment for each key
event we add
isReset are we clearing or resetting the modifier state?
kbd pointer to keyboard state (256 byte array) that owner must maintain but
that we will fill
There must be enough space in pInputs to contain 6 x up + 6 x down + 2 prefix-down + 2 prefix-up event = 16 events,
to support both the clear and reset calls.
*/
void keybd_shift(LPINPUT pInputs, int *n, BOOL isReset, LPBYTE kbd) {
if (isReset) {
keybd_shift_reset(pInputs, n, kbd);

View file

@ -142,12 +142,13 @@ LRESULT _kmnGetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
if(!InitialiseProcess(mp->hwnd)) return CallNextHookEx(Globals::get_hhookGetMessage(), nCode, wParam, lParam);
}
if(mp->message == WM_CHAR || mp->message == WM_SYSCHAR || mp->message == WM_KEYDOWN || mp->message == WM_SYSKEYDOWN || mp->message == WM_KEYUP || mp->message == WM_SYSKEYUP)
if(ShouldDebug(sdmMessage)) DebugMessage(mp, wParam);
if (mp->message >= WM_KEYFIRST && mp->message <= WM_KEYLAST && ShouldDebug(sdmMessage)) {
DebugMessage(mp, wParam);
}
if ((mp->message == WM_KEYDOWN || mp->message == WM_SYSKEYDOWN || mp->message == WM_KEYUP || mp->message == WM_SYSKEYUP)) { // I4642
BYTE scan = KEYMSG_LPARAM_SCAN(mp->lParam);
if (scan != 0xFE) {
if (scan != SCAN_FLAG_SERIALIZED_USER_KEY_EVENT) {
_td->LastScanCode = scan;
_td->LastKey = mp->wParam;
}
@ -171,15 +172,19 @@ LRESULT _kmnGetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
*/
if (flag_ShouldSerializeInput && _td->lpActiveKeyboard &&
!IsDevEnvCtrlTabSequence((wParam & PM_REMOVE) == PM_REMOVE, mp)) {
if (scan < 0xFE && mp->wParam != VK_PACKET && mp->wParam != VK_PROCESSKEY) {
if ((wParam & PM_REMOVE) == PM_REMOVE) {
// We only want to send this input once -- with PM_NOREMOVE, we will be
// processing the same message multiple times
!IsDevEnvCtrlTabSequence(wParam & PM_REMOVE, mp)) {
if (scan < SCAN_FLAG_SERIALIZED_USER_KEY_EVENT && mp->wParam != VK_PACKET && mp->wParam != VK_PROCESSKEY) {
if (wParam & PM_REMOVE) {
// We only want to send this input once -- with PM_NOREMOVE, we see the
// same message multiple times. Note: we have to bit test PM_REMOVE despite what is
// written in GetMsgProc documentation at
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644981(v=vs.85).aspx
// because we have seen undocumented situations where other flags are passed in
// to wParam, e.g. 0x0003
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wVk = (WORD)mp->wParam;
input.ki.wScan = 0xFE;
input.ki.wScan = SCAN_FLAG_SERIALIZED_USER_KEY_EVENT;
input.ki.time = mp->time;
input.ki.dwExtraInfo = mp->lParam; // We'll copy this back later
input.ki.dwFlags =
@ -199,7 +204,7 @@ LRESULT _kmnGetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
case VK_MENU:
case VK_CONTROL:
case VK_SHIFT:
if (scan != 0xFF) { // I4793
if (scan != SCAN_FLAG_KEYMAN_KEY_EVENT) { // I4793
ProcessModifierChange((UINT)mp->wParam, mp->message == WM_KEYUP || mp->message == WM_SYSKEYUP, KEYMSG_FLAG_EXTENDED(mp->lParam));
}
break;
@ -207,10 +212,10 @@ LRESULT _kmnGetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
// 4 Aug 2003 - mcdurdin - Stuff any Keyman wm_key* message with the correct scancode
if (mp->wParam != VK_BACK) {
if (scan == 0xFE) {
if (scan == SCAN_FLAG_SERIALIZED_USER_KEY_EVENT) {
mp->lParam = GetMessageExtraInfo();
SetMessageExtraInfo(0);
} else if(scan == 0xFF) {
} else if(scan == SCAN_FLAG_KEYMAN_KEY_EVENT) {
mp->lParam = (mp->lParam & 0xFF00FFFFL) | (MapVirtualKey((UINT)mp->wParam, 0) << 16);
}
}

View file

@ -140,7 +140,7 @@ BOOL KeyLanguageSwitchPress(WPARAM wParam, BOOL extended, BOOL isUp, DWORD Shift
//ReportActiveKeyboard(_td, 0);
Globals::PostControllers(wm_keyman_control, MAKELONG(KMC_INTERFACEHOTKEY, hotkey->Target), 0);
PostDummyKeyEvent(); // I4124 // I4844
keybd_event(VK_SHIFT, 0xFF, KEYEVENTF_KEYUP, 0); // I4203
keybd_event(VK_SHIFT, SCAN_FLAG_KEYMAN_KEY_EVENT, KEYEVENTF_KEYUP, 0); // I4203
return TRUE;
}

View file

@ -114,6 +114,9 @@
#define KEYMSG_FLAG_REPEAT(lParam) (HIWORD(lParam) & KF_REPEAT ? 1 : 0)
#define KEYMSG_FLAG_UP(lParam) (HIWORD(lParam) & KF_UP ? 1 : 0)
#define SCAN_FLAG_SERIALIZED_USER_KEY_EVENT 0xFE
#define SCAN_FLAG_KEYMAN_KEY_EVENT 0xFF
/***************************************************************************/
typedef struct tagSTORE