|
///////////////////////////////////////////////////////////////
//
// HotKeyCtrlEx.cpp
//
// Created: rhare - 21/07/2005
// Copyright (c) 2005 Ralph Hare (ralph.hare@ysgyfarnog.co.uk)
// All rights reserved.
//
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
//
///////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HotKeyCtrlEx.h"
#include "tstring.h"
#include <atlmisc.h>
namespace
{
WORD GetModifier( DWORD vkCode )
{
switch( vkCode )
{
case VK_LCONTROL:
case VK_RCONTROL:
return HOTKEYF_CONTROL;
case VK_LMENU:
case VK_RMENU:
return HOTKEYF_ALT;
case VK_LSHIFT:
case VK_RSHIFT:
return HOTKEYF_SHIFT;
}
return 0;
}
bool IsFunctionKey( WORD vkCode )
{
return ( vkCode >= VK_F1 ) && ( vkCode <= VK_F24 );
}
template< typename T, typename U >
bool CheckFlag( T val, U flag )
{
return static_cast< U >( val & flag ) == flag;
}
void NotifyParent( HWND hWnd )
{
::SendMessage(
::GetParent( hWnd ),
WM_COMMAND,
MAKELONG( 0x0300, ::GetDlgCtrlID( hWnd ) ),
NULL
);
}
tstring GetHotKeyText( WORD vkCode, WORD modifiers )
{
if( vkCode == 0 )
{
return _T( "" );
}
tostringstream os;
if( CheckFlag( modifiers, HOTKEYF_CONTROL ) )
{
os << _T( "Ctrl+" );
}
if( CheckFlag( modifiers, HOTKEYF_ALT ) )
{
os << _T( "Alt+" );
}
if( CheckFlag( modifiers, HOTKEYF_SHIFT ) )
{
os << _T( "Shift+" );
}
DWORD keyName = ::MapVirtualKey( vkCode, 0 ) << 16;
keyName |= ( CheckFlag( modifiers, HOTKEYF_EXT ) ? 0x1000000 : 0 );
TCHAR buffer[ 64 ] = { 0 };
::GetKeyNameText( keyName, buffer, 64 );
if( _tcslen( buffer ) > 1 )
{
_tcslwr( buffer + 1 );
}
os << buffer;
return os.str();
}
BOOL __stdcall SetWindowText( HWND hWnd, const tstring &str )
{
return ::SetWindowText( hWnd, str.c_str() );
}
}
HotKeyCtrlEx::HotKeyCtrlEx() :
m_hWnd( 0 ),
m_vkCode( 0 ),
m_modifiers( 0 ),
m_activeModifiers( 0 ),
m_keyHook()
{
}
HotKeyCtrlEx::~HotKeyCtrlEx()
{
m_keyHook.Shutdown();
}
HotKeyCtrlEx & HotKeyCtrlEx::operator = ( HWND hWnd )
{
m_hWnd = hWnd;
m_keyHook.Initialise( this );
return *this;
}
void HotKeyCtrlEx::GetHotKey( WORD &vkCode, WORD &modifiers )
{
vkCode = m_vkCode;
modifiers = m_modifiers;
}
void HotKeyCtrlEx::SetHotKey( WORD vkCode, WORD modifiers )
{
m_vkCode = vkCode;
m_modifiers = modifiers;
::SetWindowText( m_hWnd, GetHotKeyText( vkCode, modifiers ).c_str() );
}
LRESULT HotKeyCtrlEx::OnKeyDown( const KBDLLHOOKSTRUCT *pks )
{
WORD modifier = GetModifier( pks->vkCode );
if( modifier )
{
m_activeModifiers |= modifier;
return 0;
}
else if( ( pks->vkCode == VK_TAB ) &&
( CheckFlag( m_activeModifiers, HOTKEYF_CONTROL ) == false ) )
{
return 0;
}
else
{
m_modifiers = m_activeModifiers;
if( CheckFlag( pks->flags, LLKHF_EXTENDED ) )
{
m_modifiers |= HOTKEYF_EXT;
}
else
{
m_modifiers &= ~HOTKEYF_EXT;
}
m_vkCode = static_cast< WORD >( ::MapVirtualKey( pks->scanCode, 1 ) );
if( ( m_modifiers == 0 ) ||
( m_modifiers == HOTKEYF_SHIFT ) )
{
//
// Only function keys are valid hot-keys when used
// without a modifier
//
if( IsFunctionKey( m_vkCode ) == false )
{
m_vkCode = 0;
}
}
::SetWindowText( m_hWnd, GetHotKeyText( m_vkCode, m_modifiers ).c_str() );
NotifyParent( m_hWnd );
}
return 1;
}
LRESULT HotKeyCtrlEx::OnKeyUp( const KBDLLHOOKSTRUCT *pks )
{
WORD modifier = GetModifier( pks->vkCode );
if( modifier )
{
m_activeModifiers &= ~modifier;
}
return 0;
}
LRESULT HotKeyCtrlEx::OnKeyHook( UINT uMsg, const KBDLLHOOKSTRUCT *pks )
{
if( GetFocus() == m_hWnd )
{
LRESULT ret = 0;
switch( uMsg )
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
ret = OnKeyDown( pks );
break;
case WM_KEYUP:
case WM_SYSKEYUP:
ret = OnKeyUp( pks );
break;
}
return ret;
}
return 0;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.
A list of licenses authors might use can be found here
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.