menu.c

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

C
1,289
字号
                DeleteMenu( parent->menu_handle, i, MF_BYPOSITION );
                break;
            }
        }
        m->menu_handle = NULL;
    }
} /* burnMenu */

/*
 * freeMenu - destroy and free all data associated with a menu
 */
static void freeMenu( menu *parent, menu *m )
{
    int     offset;

    assert( m != NULL && parent != NULL && parent->num_items > 0 );
    clearMenu( m );
    for( offset = 0; offset < parent->num_items; offset++ ) {
        if( GetSubMenu( parent->menu_handle, offset ) == m->menu_handle ) {
            DeleteMenu( parent->menu_handle, offset, MF_BYPOSITION );
            break;
        }
    }
    if( m->menu_handle ) {
        DestroyMenu( m->menu_handle );
    }
    parent->num_items -= 1;
    DeleteLLItem( &parent->item_head, &parent->item_tail, (ss*)m );
    MemFree( m );

} /* freeMenu */

/*
 * makeItem - add an item to a menu
 */
static void makeItem( menu *m, item *citem )
{
    if( !citem->in_menu ) {
        assert( m->menu_handle != NULL );
        if( citem->id != 0 ) {
            AppendMenu( m->menu_handle, MF_ENABLED | MF_STRING, citem->id,
                                &citem->name[0] );
        } else {
            AppendMenu( m->menu_handle, MF_SEPARATOR, 0, NULL );
        }
        citem->in_menu = TRUE;
    }

} /* makeItem */

/*
 * makeMenu - make a new menu
 */
static void makeMenu( menu *parent, menu *m )
{
    item    *i;

    assert( parent->menu_handle != NULL && m->menu_handle == NULL );
    m->menu_handle = CreatePopupMenu();
    AppendMenu( parent->menu_handle, MF_ENABLED | MF_POPUP,
                        (UINT) m->menu_handle, &m->name[0] );
    for( i = m->item_head; i != NULL; i = i->next ) {
        i->in_menu = FALSE;
        makeItem( m, i );
    }

} /* makeMenu */


/*
 * These are the routines which are used to create and add to menus
 */

/*
 * StartMenu - start a new menu; MenuItem will be used to add to this
 */
int StartMenu( char *data )
{
    char        name[ MAX_STR ];
    char        help[ MAX_STR ];
    bool        need_hook;

    if( currMenu != NULL ) {
        return( ERR_INVALID_MENU );
    }

    GetStringWithPossibleQuote( data, name );
    GetStringWithPossibleQuote( data, help );
    RemoveLeadingSpaces( data );
    need_hook = FALSE;
    if( data[0] != 0 ) {
        need_hook = TRUE;
    }
    /* check for an existing menu with the same name */
    currMenu = findMenu( rootMenu, name );
    if( currMenu == NULL ) {
        currMenu = addMenuToMenu( rootMenu, name, help );
    } else {
        clearMenu( currMenu );
    }
    currMenu->need_hook = need_hook;
    return( ERR_NO_ERR );

} /* StartMenu */

/*
 * MenuItem - add an item to the current menu
 */
int MenuItem( char *data )
{
    char        name[ MAX_STR ];
    char        help[ MAX_STR ];

    if( currMenu == NULL ) {
        return( ERR_INVALID_MENU );
    }
    GetStringWithPossibleQuote( data, name );
    GetStringWithPossibleQuote( data, help );
    RemoveLeadingSpaces( data );
    TranslateTabs( name );
    addItemToMenu( currMenu, name, help, data, FALSE );
    return( ERR_NO_ERR );

} /* MenuItem */

/*
 * AddMenuItem - add an item to a specific menu
 */
int AddMenuItem( char *data )
{
    char        menu_name[ MAX_STR ];
    char        name[ MAX_STR ];
    char        help[ MAX_STR ];
    menu        *m;

    GetStringWithPossibleQuote( data, menu_name );
    GetStringWithPossibleQuote( data, name );
    GetStringWithPossibleQuote( data, help );
    RemoveLeadingSpaces( data );
    m = findMenu( rootMenu, menu_name );
    if( m != NULL ) {
        addItemToMenu( m, name, help, data, FALSE );
        InitMenu();
        return( ERR_NO_ERR );
    }
    return( ERR_INVALID_MENU );

} /* AddMenuItem */

/*
 * DoMenuChar - handle a menu activated by the keyboard
 */
int DoMenuChar( void )
{
    int         key;
    menu        *m;
    item        *citem;
    char        *str;
    int         len;

    key = LastEvent;
    for( m = rootMenu->item_head; m != NULL; m = m->next ) {
        if( getHotKey( m->name ) == key ) {
            if( selectedItem > 0 ) {
                key = selectedItem;
                selectedItem = 0;
            } else {
                key = GetNextEvent( TRUE );
            }
            for( citem = m->item_head; citem != NULL; citem = citem->next ) {
                if( getHotKey( citem->name ) == key ) {
                    len = strlen( citem->cmd ) + 1;
                    str = alloca( len );
                    memcpy( str, citem->cmd, len );
                    return( RunCommandLine( str ) );
                }
            }
        }
    }
    return( ERR_NO_ERR );

} /* DoMenuChar */

/*
 * ViEndMenu - stop adding a top level menu
 */
int ViEndMenu( void )
{
    int ch;

    if( currMenu == NULL ) {
        return( ERR_INVALID_MENU );
    }
    ch = getHotKey( currMenu->name );
    if( ch >= VI_KEY( ALT_A  )&& ch <= VI_KEY( ALT_Z  )) {
        EventList[ ch ].rtn.old = DoMenuChar;
        EventList[ ch ].alt_rtn.old = DoMenuChar;
        EventList[ ch ].ins = IMMenuKey;
        EventList[ ch ].b.keep_selection = TRUE;
    }
    if( !isSpecialMenuPtr( currMenu ) ) {
        InitMenu();
    }
    currMenu = NULL;
    return( ERR_NO_ERR );

} /* EndMenu */

/*
 * These are the routines which are used to Destroy and Delete menus and
 * items in menus
 */

/*
 * DoItemDelete - delete an item from a menu
 */
int DoItemDelete( char *data )
{
    menu    *m;
    char    name[ MAX_STR ];
    char    parm[ MAX_STR ];
    int     offset;

    NextWord1( data, name );
    m = findMenu( rootMenu, name );
    if( m != NULL ) {
        NextWord1( data, parm );
        offset = atoi( parm );
        if( freeItem( m, offset ) ) {
            InitMenu();
            return( ERR_NO_ERR );
        }
    }
    return( ERR_INVALID_MENU );

} /* DoItemDelete */

/*
 * DoMenuDelete - handle deleting a menu
 */
int DoMenuDelete( char *data )
{
    menu    *m;

    RemoveLeadingSpaces( data );
    m = specialMenu( data );
    if( m == NULL ) {
        m = findMenu( rootMenu, data );
        if( m != NULL ) {
            freeMenu( rootMenu, m );
            InitMenu();
            return( ERR_NO_ERR );
        }
    }
    return( ERR_INVALID_MENU );

} /* DoMenuDelete */

/*
 * Initialize our menus
 */
int InitMenu( void )
{
    menu    *m;

    if( Root ) {
        if( rootMenu->menu_handle != NULL ) {
            /* pitch all Windows objects */
            for( m = (menu *)rootMenu->item_head; m != NULL; m = m->next ) {
                burnMenu( rootMenu, m );
            }
            DestroyMenu( rootMenu->menu_handle );
        }
        rootMenu->menu_handle = CreateMenu();
        if( EditFlags.Menus ) {
            for( m = (menu *)rootMenu->item_head; m != NULL; m = m->next ) {
                m->menu_handle = NULL;
                makeMenu( rootMenu, m );
            }
        }
        SetMenu( Root, rootMenu->menu_handle );
    }
    return( ERR_NO_ERR );

} /* InitMenu */



int FiniMenu( void )
{
    menu    *m, *next;

    if( Root ) {
        if( rootMenu->menu_handle != NULL ) {
            for( m = (menu *)rootMenu->item_head; m != NULL; ) {
                next = m->next;
                if( m->menu_handle ) {
                    clearMenu( m );
                    // DestroyMenu( m->menu_handle );
                }
                DeleteLLItem( &rootMenu->item_head, &rootMenu->item_tail, (ss*)m );
                MemFree( m );
                m = next;
            }
            // DestroyMenu( rootMenu->menu_handle );
        }
    }
    return( 0 );
}


/*
 * IsMenuHotKey - decide if a specific alt key is a menu hot key
 */
int IsMenuHotKey( int ch )
{
    menu    *m;

    ch = ch - 'A' + VI_KEY( ALT_A );
    for( m = rootMenu->item_head; m != NULL; m = m->next ) {
        if( getHotKey( m->name ) == ch ) {
            return( TRUE );
        }
    }
    return( FALSE );

} /* IsMenuHotKey */;

/*
 * doFloatMenu - create a floating popup menu
 */
static int doFloatMenu( int id, int x, int y )
{
    menu        *m;
    HMENU       f;
    item        *citem;
    POINT       p;

    assert( id >= 0 && id < MAX_FLOAT_MENUS );
    m = &floatMenus[ id ];
    f = CreatePopupMenu();
    citem = m->item_head;
    while( citem != NULL ) {
        if( citem->name == NULL ) {
            AppendMenu( f, MF_SEPARATOR, 0, NULL );
        } else {
            AppendMenu( f, MF_ENABLED | MF_STRING, citem->id, citem->name );
        }
        citem = citem->next;
    }
    p.x = x;
    p.y = y;
    ClientToScreen( CurrentWindow, &p );
    TrackPopupMenu( f, 0, p.x, p.y, 0, Root, NULL );
    DestroyMenu( f );
    return( ERR_NO_ERR );

} /* doFloatMenu */

/*
 * ActivateFloatMenu - activate floating menu
 */
int ActivateFloatMenu( char *data )
{
    char        str[MAX_STR];
    int         id, len, x, y;

    /*
     * get input syntax :
     * FLOATMENU id len x y
     */
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    id = atoi( str );
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    len = atoi( str );
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    x = atoi( str );
    if( NextWord1( data, str ) <= 0 ) {
        return( ERR_INVALID_MENU );
    }
    y = atoi( str );
    return( doFloatMenu( id, x, y ) );

} /* ActivateFloatMenu */

/*
 * MenuCommand: returns TRUE if it handles the command and
 * FALSE otherwise. Looks for a menu item with id identical to
 * the one passed in.
 */
int MenuCommand( UINT w )
{
    menu    *m;
    int     rc;

    if( !w || EditFlags.HoldEverything ) {
        return( ERR_NO_ERR );
    }
    rc = HandleToolCommand( w );
    if( rc != MENU_COMMAND_NOT_HANDLED ) {
        // SetFocus( Root ); // can't do this -- we have an ideactivate button
        return( rc );
    } else {
        rc = specialMenuCommand( w );
        if( rc != MENU_COMMAND_NOT_HANDLED ) {
            return( rc );
        } else {
            for( m = rootMenu->item_head; m != NULL; m = m->next ) {
                rc = handleMenuCommand( m, w );
                if( rc != MENU_COMMAND_NOT_HANDLED ) {
                    return( rc );
                }
            }
        }
    }
    return( MENU_COMMAND_NOT_HANDLED );

} /* MenuCommand */

static void tabs_to_slash_t( char *buffer, char *text )
{
    while( *text != 0 ) {
        if( *text == '\t' ) {
            *buffer = '\\';

⌨️ 快捷键说明

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