guimapky.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 649 行 · 第 1/2 页

C
649
字号
        case VK_HOME:
            *key= GUIMapKey( GUI_KEY_HOME );
            break;
        case VK_END:
            *key= GUIMapKey( GUI_KEY_END );
            break;
        case VK_UP:
            *key= GUIMapKey( GUI_KEY_UP );
            break;
        case VK_DOWN:
            *key= GUIMapKey( GUI_KEY_DOWN );
            break;
        case VK_LEFT:
            *key= GUIMapKey( GUI_KEY_LEFT );
            break;
        case VK_RIGHT:
            *key= GUIMapKey( GUI_KEY_RIGHT );
            break;
        case VK_INSERT:
            *key= GUIMapKey( GUI_KEY_INSERT );
            break;
        case VK_DELETE:
            *key= GUIMapKey( GUI_KEY_DELETE );
            break;
        case VK_PRIOR:
            *key= GUIMapKey( GUI_KEY_PAGEUP );
            break;
        case VK_NEXT:
            *key= GUIMapKey( GUI_KEY_PAGEDOWN );
            break;
        case VK_SPACE :
            *key = GUIMapKey( GUI_KEY_SPACE );
            break;
        case VK_F11 :
            *key = GUIMapKey( GUI_KEY_F11 );
            break;
        case VK_F12 :
            *key = GUIMapKey( GUI_KEY_F12 );
            break;
#ifdef __OS2_PM__
        case VK_BACKTAB:
            *key= GUI_KEY_SHIFT_TAB;
            break;
#else
        case VK_DECIMAL:
            *key = GUIMapKey( GUI_KEY_KP_PERIOD );
            break;
        case VK_ADD :
            *key = GUIMapKey( GUI_KEY_KP_PLUS );
            break;
        case VK_SUBTRACT :
            *key = GUIMapKey( GUI_KEY_KP_MINUS );
            break;
        case VK_DIVIDE :
            *key = GUIMapKey( GUI_KEY_KP_SLASH );
            break;
        case VK_MULTIPLY :
            *key = GUIMapKey( GUI_KEY_KP_ASTERISK );
            break;
#endif
        default:
            if( convert_keytable( vk, key ) ) {
                return( *key != 0 );
            }
            // the rest of this case assumes that vk is ascii
            if( convert_ascii( vk, key ) ) break;
            return( FALSE );
            break;
        }
    }

    return( TRUE );
}

/*
 *  GUISetKeyState
 */

void GUISetKeyState( void )
{
    int         vk_cap;
    bool        shift;
    bool        caplock;

    KeyState = GUI_KS_NONE;
    shift = _wpi_getkeystate( VK_SHIFT ) < 0;

    vk_cap = _wpi_getkeystate( VK_CAPITAL );
    /* vk_cap & 0x80 is caplock pressed.
     * vk_cap & 0x01 indicates and odd number of toggles since the system
     * was started.
     */
    caplock = ( ( vk_cap & 0x8000 ) && !( vk_cap & 0x0001 ) ) ||
              ( ( vk_cap & 0x0001 ) && !( vk_cap & 0x8000 ) );
    if( ( shift && !caplock ) || ( caplock && !shift ) ) {
        KeyState |= GUI_KS_SHIFT;
    }
    if( _wpi_getkeystate( VK_CONTROL ) < 0 ) {
        KeyState |= GUI_KS_CTRL;
    }
#ifndef __OS2_PM__
    if( _wpi_getkeystate( VK_MENU ) < 0 ) {
        KeyState |= GUI_KS_ALT;
    }
#else
    if( _wpi_getkeystate( VK_ALT ) < 0 ) {
        KeyState |= GUI_KS_ALT;
    }
#endif
}

#ifndef __OS2_PM__
bool GUIWindowsMapKey( WPI_PARAM1 vk, WPI_PARAM2 data, gui_key *scan )
{
    if( scan == NULL ) {
        return( FALSE );
    }
    GUISetKeyState();
    *scan = HIWORD( LOBYTE( data ) );
    return( GUIConvertVirtKeyToGUIKey( (WORD) vk, scan ) );
}

WPI_MRESULT GUIProcesskey( HWND hwnd, WPI_MSG msg, WPI_PARAM1 wparam,
                           WPI_PARAM2 lparam )
{
    gui_window          *wnd;
    gui_key_state       key_state;
    gui_event           gui_ev;
    HWND                low_l;

    wnd=wnd;
    switch( msg ) {
    case WM_MENUCHAR :
        low_l = GET_WM_COMMAND_HWND( wparam, lparam );
        if( low_l == 0 && RetTrue ) {
            /* app used last WM_SYSMENU key and there are no menus open,
               so tell windows not to beep */
            return( MAKELONG( 0, 1 ) );
        } else {
#ifndef __OS2_PM__
            // if the last syskey was not recognized as a macro key
            // then lets check to see of the key press could have
            // activated the main menu
            wnd = GUIGetWindow( hwnd );
            if( wnd && wnd->parent == GUIGetRootWindow() ) {
                PostMessage(wnd->parent->root, WM_SYSCOMMAND, SC_KEYMENU, wparam);
                return( MAKELONG( 0, 1 ) );
            } else {
                return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) );
            }
#else
            return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) );
#endif
        }
    case WM_SYSKEYDOWN :
    case WM_SYSKEYUP :
        if( GUICurrWnd != NULL ) {
            GUIGetKeyState( &key_state.state );
            if( GUIWindowsMapKey( wparam, 0, &key_state.key ) ) {
                if( msg == WM_SYSKEYDOWN  ) {
                    gui_ev = GUI_KEYDOWN;
                } else {
                    gui_ev = GUI_KEYUP;
                }
                RetTrue = GUIEVENTWND( GUICurrWnd, gui_ev, &key_state );
                if( RetTrue ) {
                    return( 0l ); // app used key, don't send to windows
                }
            }
        }
        return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) );
    case WM_KEYUP :
        if( ( GUICurrWnd != NULL ) && !EditControlHasFocus ) {
            GUIGetKeyState( &key_state.state );
            if( GUIWindowsMapKey( wparam, lparam, &key_state.key ) ) {
                GUIEVENTWND( GUICurrWnd, GUI_KEYUP, &key_state );
            }
        }
        break;
    case WM_KEYDOWN :
        if( ( GUICurrWnd != NULL ) && !EditControlHasFocus ) {
            GUIGetKeyState( &key_state.state );
            if( GUIWindowsMapKey( wparam, lparam, &key_state.key ) ) {
                GUIEVENTWND( GUICurrWnd, GUI_KEYDOWN, &key_state );
            }
        }
        break;
    }
    return( (WPI_MRESULT)MAKELONG( 0, 1 ) );
}
#else

typedef struct {
    gui_key     key;
    char        scan;
} ctrlkey;

static ctrlkey ctrl_table[] = {
    GUI_KEY_CTRL_BACKSLASH,             43,
    GUI_KEY_CTRL_RIGHT_BRACKET,         27,
    GUI_KEY_CTRL_LEFT_BRACKET,          26,
    GUI_KEY_CTRL_6,                     7,
    GUI_KEY_CTRL_MINUS,                 12,
    GUI_KEY_CTRL_BACKSPACE,             14,
    GUI_KEY_CTRL_ENTER,                 28,
    GUI_KEY_CTRL_MINUS,                 12,
    GUI_KEY_CTRL_2,                     3,
    GUI_KEY_CTRL_KP_SLASH,              92,
    GUI_KEY_CTRL_KP_ASTERISK,           55,
    GUI_KEY_CTRL_KP_MINUS,              74,
    GUI_KEY_CTRL_KP_PLUS,               78,
    GUI_KEY_CTRL_8,                     9
};

static ctrlkey alt_table[] = {
    GUI_KEY_ALT_1,      '1',
    GUI_KEY_ALT_2,      '2',
    GUI_KEY_ALT_3,      '3',
    GUI_KEY_ALT_4,      '4',
    GUI_KEY_ALT_5,      '5',
    GUI_KEY_ALT_6,      '6',
    GUI_KEY_ALT_7,      '7',
    GUI_KEY_ALT_8,      '8',
    GUI_KEY_ALT_9,      '9',
    GUI_KEY_ALT_0,      '0',
    GUI_KEY_ALT_MINUS,  '-',
    GUI_KEY_ALT_EQUAL,  '=',
};

static bool convert_table( WORD vk, gui_key *key, ctrlkey *table, int size )
{
    int         i;

    for( i=0; i < size; i++ ) {
        if( vk == table[i].scan ) {
            *key = table[i].key;
            return( TRUE );
        }
    }
    return( FALSE );
}

bool GUIWindowsMapKey( WPI_PARAM1 p1, WPI_PARAM2 p2, gui_key *key )
{
    WORD        flags;
    WORD        vk;
    char        ch;
    char        scan;
    char        pm_scan;

    flags       = SHORT1FROMMP( p1 );
    vk          = SHORT2FROMMP( p2 );
    ch          = CHAR1FROMMP( p2 );
    scan        = CHAR2FROMMP( p2 );
    pm_scan     = CHAR4FROMMP( p1 );

    if( flags & ( KC_DEADKEY | KC_COMPOSITE ) ) {
        return( FALSE );
    } else if( flags & KC_VIRTUALKEY ) {
        return( GUIConvertVirtKeyToGUIKey( vk, key ) );
    } else if( ( flags & KC_CHAR ) && ( ch != 0 ) && ( ch != 0xe0 ) ) {
        return( convert_ascii( ch, key ) );
    } else if( ( flags & KC_LONEKEY ) && ( ch != 0 ) && ( ch != 0xe0 ) ) {
        return( convert_ascii( ch, key ) );
    } else if( flags & KC_SCANCODE ) {
        if( CTRL ) {
            if( convert_table( pm_scan, key, ctrl_table,
                               sizeof(ctrl_table) / sizeof(ctrl_table[0]) ) ) {
                return( TRUE );
            }
            if( convert_alpha( ch, key ) ) return( TRUE );
            return( FALSE );
        } else {
            if( convert_table( ch, key, alt_table,
                               sizeof(alt_table) / sizeof(alt_table[0]) ) ) {
                return( TRUE );
            }
            *key = (gui_key ) ( pm_scan + GUI_SCAN_OFFSET ) ;
            return( TRUE );
        }
    }
    return( FALSE );
}

WPI_MRESULT GUIProcesskey( HWND hwnd, WPI_MSG msg, WPI_PARAM1 wparam,
                           WPI_PARAM2 lparam )
{
    WORD                key_flags;
    gui_key_state       key_state;
    gui_event           gui_ev;

    hwnd = hwnd;
    key_flags = SHORT1FROMMP( wparam );

    if( msg == WM_TRANSLATEACCEL ) {
        // Don't let OS/2 process F10 as an accelerator
        // Note: similar code exists in guixwind.c but we need to
        // take different default action
        PQMSG   pqmsg = wparam;
        USHORT  flags = SHORT1FROMMP(pqmsg->mp1);
        USHORT  vkey  = SHORT2FROMMP(pqmsg->mp2);

        if( (flags & KC_VIRTUALKEY) && (vkey == VK_F10) )
            return( (WPI_MRESULT)FALSE );

        return( _wpi_defwindowproc( hwnd, msg, wparam, lparam ) );
    }
    if( ( GUICurrWnd != NULL ) && !EditControlHasFocus ) {
        if( msg == WM_CHAR ) {
            if( key_flags & KC_KEYUP ) {
                gui_ev = GUI_KEYUP;
            } else {
                gui_ev = GUI_KEYDOWN;
            }
            GUIGetKeyState( &key_state.state );
            if( GUIWindowsMapKey( wparam, lparam, &key_state.key ) ) {
                return( (WPI_MRESULT)(GUIEVENTWND( GUICurrWnd, gui_ev, &key_state ) ) );
            }
        }
    }
    return( (WPI_MRESULT)FALSE );
}
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?