Click here to Skip to main content
15,886,065 members
Articles / Web Development / HTML

Mouse Gestures for Internet Explorer

Rate me:
Please Sign up or sign in to vote.
4.84/5 (99 votes)
21 Sep 200514 min read 1.3M   13.4K   235  
Adding mouse gesture recognition to Internet Explorer.
///////////////////////////////////////////////////////////////
//
// 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.

License

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


Written By
Web Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions