From: Hector Santos on
hamishd wrote:

> How do I catch a SHIFT + TAB ?
>
>
> BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
> {
> if (pMsg->message == WM_KEYDOWN){
> if(pMsg->wParam == VK_TAB && pMsg->lParam == VK_SHIFT){
> //do stuff
> }
>
> return CFrameWnd::PreTranslateMessage(pMsg);
> }


You can use a simple logic like so:

First, add the following variable member to your CMainFrame.h class:.

BOOL m_shift

Don't forget to initialize it to FALSE in the CMainFrame constructor,
then use this logic in PreTranslateMessage()

BOOL CMainFrame::::PreTranslateMessage(MSG* pMsg)
{
switch(pMsg->message) {
case WM_KEYDOWN:
if (pMsg->wParam == VK_SHIFT) m_shift = TRUE;
if (m_shift && pMsg->wParam == VK_TAB) {
TRACE("- GOT SHIFT-TAB - PRESSING\n");
}
break;
case WM_KEYUP:
if (pMsg->wParam == VK_SHIFT) m_shift = FALSE;
if (m_shift && pMsg->wParam == VK_TAB) {
TRACE("- GOT SHIFT-TAB - RELEASED\n");
}
break;
}
return CWinApp::PreTranslateMessage(pMsg);
}

There are other ways as well, but I the above was alwsys easier. Its a
trimmed version of a CKeyCodeCheck() class used for my MFC terminal
emulator applet that allows me to do key checking w/o combinations of
ctl, alt and/or shift keys:

BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
if (keycode.Pressed(pMsg, VK_TAB, VK_SHIFT)) {
TRACE("- GOT SHIFT-TAB - PRESSED (DOWN)\n");
}
if (keycode.Released(pMsg, VK_TAB, VK_SHIFT )) {
TRACE("- GOT SHIFT-TAB - RELEASED\n");
}
if (keycode.Released(pMsg, VK_TAB, VK_CONTROL, VK_MENU)) {
TRACE("- GOT CTRL-ALT-TAB - RELEASED\n");
}
if (keycode.Released(pMsg, VK_F8)) {
TRACE("- GOT F8 - RELEASED\n");
}
if (keycode.Released(pMsg, VK_F8, VK_MENU)) {
TRACE("- GOT ALT F8 - RELEASED\n");
}
return CFrameWnd::PreTranslateMessage(pMsg);
}

Here is the source:

//---------------------------------------------------------
// (c) 2001 Santronics Software, Inc.
// KeyCodeCheck.h

#pragma once

//
const DWORD VK_SCA_S = 0x0001; // SHIFT
const DWORD VK_SCA_C = 0x0002; // CTRL
const DWORD VK_SCA_A = 0x0004; // ALT
const DWORD VK_ALT = VK_MENU;

class CKeyCodeCheck
{
public:
CKeyCodeCheck(): m_sca(0)
{}
public:
BOOL Pressed(MSG* pMsg, UINT vkey, UINT vk1 = 0, UINT vk2 = 0,
UINT vk3 = 0);
BOOL Released(MSG* pMsg, UINT vkey, UINT vk1 = 0, UINT vk2 = 0,
UINT vk3 = 0);
protected:
BOOL ProcessKey(MSG* pMsg, UINT vkey, UINT scabits);
UINT MaskVKBits(UINT scabits, UINT vk);
UINT m_sca;
};

//---------------------------------------------------------
// (c) 2001 Santronics Software, Inc.
// KeyCodeCheck.cpp

#include "StdAfx.h"
#include "KeyCodeCheck.h"

UINT CKeyCodeCheck::MaskVKBits(UINT scabits, UINT vk)
{
if (vk != 0) {
if (vk == VK_SHIFT) scabits |= VK_SCA_S;
if (vk == VK_CONTROL) scabits |= VK_SCA_C;
if (vk == VK_ALT) scabits |= VK_SCA_A;
}
return scabits;
}

BOOL CKeyCodeCheck::ProcessKey(MSG* pMsg, UINT vkey, UINT scabits)
{
switch(pMsg->message) {
case WM_KEYDOWN:
case WM_KEYUP:
if (pMsg->message == WM_KEYDOWN) {
if (pMsg->wParam == VK_SHIFT) m_sca |= VK_SCA_S;
if (pMsg->wParam == VK_ALT) m_sca |= VK_SCA_A;
if (pMsg->wParam == VK_CONTROL) m_sca |= VK_SCA_C;
} else {
if (pMsg->wParam == VK_SHIFT) m_sca &= ~VK_SCA_S;
if (pMsg->wParam == VK_ALT) m_sca &= ~VK_SCA_A;
if (pMsg->wParam == VK_CONTROL) m_sca &= ~VK_SCA_C;
}
if (pMsg->wParam == vkey) {
if ((scabits==0 && m_sca==0) ||
((scabits && m_sca) && ((m_sca & scabits)==scabits))) {
return TRUE;
}
}
break;
}
return FALSE;
}


BOOL CKeyCodeCheck::Pressed(MSG* pMsg, UINT vkey, UINT vk1 /* = 0 */,
UINT vk2 /* = 0 */, UINT vk3 /* = 0 */)
{
if (pMsg->message == WM_KEYDOWN) {
UINT scabits = 0;
scabits = MaskVKBits(scabits,vk1);
scabits = MaskVKBits(scabits,vk2);
scabits = MaskVKBits(scabits,vk3);
return ProcessKey(pMsg,vkey,scabits);
}
return FALSE;
}

BOOL CKeyCodeCheck::Released(MSG* pMsg, UINT vkey, UINT vk1 /* = 0 */,
UINT vk2 /* = 0 */, UINT vk3 /* = 0 */)
{
if (pMsg->message == WM_KEYUP) {
UINT scabits = 0;
scabits = MaskVKBits(scabits,vk1);
scabits = MaskVKBits(scabits,vk2);
scabits = MaskVKBits(scabits,vk3);
return ProcessKey(pMsg,vkey,scabits);
}
return FALSE;
}

To use it, just add a member to your CMainFrame class:

#include "KeyCodeCheck.h"

class CMainFrame : public CFrameWnd
{
.....

public:
CKeyCodeCheck keycode;
};

--
HLS