⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 w_menu.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <windows.h>
#include <string.h>
#include "wglbl.h"
#include "wmem.h"
#include "wmenu.h"
#include "winfo.h"
#include "wribbon.h"
#include "wstrdup.h"
#include "wcopystr.h"
#include "wresall.h"
#include "wmsg.h"
#include "wmsgfile.gh"
#include "wrutil.h"
#include "w_menu.h"

/****************************************************************************/
/* external function prototypes                                             */
/****************************************************************************/

/****************************************************************************/
/* macro definitions                                                        */
/****************************************************************************/

/****************************************************************************/
/* type definitions                                                         */
/****************************************************************************/

/****************************************************************************/
/* static function prototypes                                               */
/****************************************************************************/
static void     *WInitDataFromMenu      ( WMenuEntry *, void * );
static int      WCalcMenuSize           ( WMenuEntry * );
static int      WMakeMenuEntryFromData  ( void **, int *, WMenuEntry *,
                                          WMenuEntry **, Bool );
static int      WAllocMenuEntryFromData ( void **, int *, WMenuEntry **,
                                          Bool );
static int      WMakeMenuItemFromData   ( void **data, int *size,
                                          MenuItem **new, Bool );
static Bool     WInsertEntryIntoPreview ( WMenuEditInfo *, WMenuEntry * );

/****************************************************************************/
/* static variables                                                         */
/****************************************************************************/
static  WMenuEntry      *WDummyMenuEntry = NULL;

void WInitDummyMenuEntry( void )
{
    WDummyMenuEntry = (WMenuEntry *) WMemAlloc( sizeof(WMenuEntry) );
    memset( WDummyMenuEntry, 0, sizeof( WMenuEntry ) );
    WDummyMenuEntry->item = ResNewMenuItem();
    WDummyMenuEntry->item->Item.Normal.ItemText =
        WAllocRCString( W_MENUITEM );
    WDummyMenuEntry->item->Item.Normal.ItemID = 101;
}

void WFiniDummyMenuEntry( void )
{
    WFreeMenuEntry( WDummyMenuEntry );
    WDummyMenuEntry = NULL;
}

WMenuEditInfo *WAllocMenuEInfo( void )
{
    WMenuEditInfo *einfo;

    einfo = (WMenuEditInfo *) WMemAlloc( sizeof(WMenuEditInfo) );

    if( einfo ) {
        memset( einfo, 0, sizeof(WMenuEditInfo) );
        einfo->current_pos = -1;
    }

    return( einfo );
}

void WFreeMenuEInfo( WMenuEditInfo *einfo )
{
    if( einfo ) {
        if( einfo->menu ) {
            WFreeMenu( einfo->menu );
            einfo->menu = NULL;
        }
        if( einfo->wsb ) {
            WDestroyStatusLine( einfo->wsb );
            einfo->wsb = NULL;
        }
        if( einfo->ribbon ) {
            WDestroyRibbon( einfo );
        }
        if( ( einfo->preview_window != (HWND)NULL ) &&
             IsWindow( einfo->preview_window ) ) {
            DestroyWindow( einfo->preview_window );
            einfo->preview_window = (HWND)NULL;
        }
        if( ( einfo->edit_dlg != (HWND)NULL ) &&
             IsWindow( einfo->edit_dlg ) ) {
            DestroyWindow ( einfo->edit_dlg );
            einfo->edit_dlg = (HWND)NULL;
        }
        if ( ( einfo->win != (HWND)NULL ) && IsWindow ( einfo->win ) ) {
            SetWindowLong( einfo->win, 0, (LONG)0 );
            DestroyWindow ( einfo->win );
            einfo->win = (HWND)NULL;
        }
        if ( einfo->file_name ) {
            WMemFree ( einfo->file_name );
        }
        WMemFree ( einfo );
    }
}

void WMakeDataFromMenu( WMenu *menu, void **data, int *size )
{
    char *tdata;

    if( data && size ) {
        *size = WCalcMenuSize( menu->first_entry ) + 2*sizeof(WORD);
        if( *size ) {
            *data = WMemAlloc( *size );
            if( *data ) {
                tdata = *data;
                memset( tdata, 0, 2*sizeof(WORD) );
                tdata = tdata + 2*sizeof(WORD);
                WInitDataFromMenu( menu->first_entry, tdata );
            }
        } else {
            *data = NULL;
        }
    }
}

int WMakeMenuItemFromData( void **data, int *size, MenuItem **new,
                           Bool is32bit )
{
    MenuItemNormal      *normal;
    char                *text;
    char                *itext;
    int                 msize;
    int                 tlen;
    int                 itlen;

    if( !data || !*data || !size || !*size || !new ) {
        return( FALSE );
    }

    *new = ResNewMenuItem();
    if( *new == NULL ) {
        return( FALSE );
    }

    normal = (MenuItemNormal *)*data;
    (*new)->Item.Normal.ItemFlags = normal->ItemFlags;
    (*new)->IsPopup = ( ( normal->ItemFlags & MENU_POPUP ) != 0 );
    msize = sizeof( MenuFlags );
    if( (*new)->IsPopup ) {
        text = (char *)(*data);
        text += msize;
    } else {
        if( !(normal->ItemFlags & ~MENU_ENDMENU ) && !normal->ItemID ) {
            (*new)->Item.Normal.ItemFlags |= MENU_SEPARATOR;
        }
        (*new)->Item.Normal.ItemID = normal->ItemID;
        msize += sizeof( uint_16 );
        text = (char *)(*data);
        text += msize;
    }
    tlen = WRStrlen( text, is32bit ) + 1;
    if( is32bit ) {
        tlen++;
    }

    if( is32bit ) {
        itext = NULL;
        WRunicode2mbcs( text, &itext, &itlen );
    } else {
        itext = (char *)WMemAlloc( tlen );
        if( itext ) {
            memcpy( itext, text, tlen );
        }
    }

    if( !itext ) {
        *size = 0;
        return( FALSE );
    }

    if( (*new)->IsPopup ) {
        (*new)->Item.Popup.ItemText = itext;
    } else {
        (*new)->Item.Normal.ItemText = itext;
    }
    text += tlen;
    msize += tlen;

    *data = text;
    if( *size >= msize ) {
        *size = *size - msize;
    } else {
        *size = 0;
        return( FALSE );
    }

    return( TRUE );
}

int WAllocMenuEntryFromData( void **data, int *size, WMenuEntry **entry,
                             Bool is32bit )
{
    int         ok;

    ok = ( data && *data && size && *size && entry );

    if( ok ) {
        *entry = (WMenuEntry *) WMemAlloc ( sizeof(WMenuEntry) );
        ok = ( *entry != NULL );
    }

    if( ok ) {
        memset( *entry, 0, sizeof(WMenuEntry) );
        (*entry)->is32bit = is32bit;
        ok = WMakeMenuItemFromData( data, size, &(*entry)->item, is32bit );
    }

    if( !ok ) {
        if ( *entry ) {
            WFreeMenuEntry ( *entry );
            *entry = NULL;
        }
    }

    return( ok );
}

int WMakeMenuEntryFromData( void **data, int *size, WMenuEntry *parent,
                            WMenuEntry **entry, Bool is32bit )
{
    int         ok;
    WMenuEntry  **current;
    WMenuEntry  *prev;

    if( !entry || !data || !size ) {
        return( FALSE );
    }

    *entry = NULL;
    ok = TRUE;

    if( !*data || !*size ) {
        return( TRUE );
    }

    current = entry;
    prev = NULL;

    while( ok && ( *size > 0 ) ) {
        ok = WAllocMenuEntryFromData( data, size, current, is32bit );
        if( ok ) {
            (*current)->parent = parent;
            (*current)->prev = prev;
            if( (*current)->item->IsPopup ) {
                ok = WMakeMenuEntryFromData ( data, size, *current,
                                              &((*current)->child), is32bit );
            }
            if( (*current)->item->Item.Normal.ItemFlags & MENU_ENDMENU ) {
                break;
            }
            prev = *current;
            current = &((*current)->next);
        }
    }

    if( !ok ) {
        if( *entry ) {
            WFreeMenuEntries( *entry );
            *entry = NULL;
        }
    }

    return( ok );
}

WMenu *WMakeMenuFromInfo ( WMenuInfo *info )
{
    WMenu       *menu;
    int         ok;
    void        *data;
    int         size;

    menu = NULL;

    ok = ( info != NULL );

    if ( ok ) {
        menu = (WMenu *) WMemAlloc ( sizeof(WMenu) );
        ok = ( menu != NULL );
    }

    if( ok ) {
        menu->first_entry = NULL;
        if( info->data != NULL ) {
            ok = ( ((WORD *)info->data)[0] == 0 );
            if( !ok ) {
                WDisplayErrorMsg( W_NOMENUEX );
            }
        }
    }

    if( ok ) {
        menu->is32bit = info->is32bit;
        if( info->data != NULL ) {
            data = ((char *)info->data) + 2*sizeof(WORD);
            size = info->data_size - 2*sizeof(WORD);
            ok = WMakeMenuEntryFromData( &data, &size, NULL,
                                         &menu->first_entry, info->is32bit );
        }
    }

    if( ok ) {
        info->data      = NULL;
        info->data_size = 0;
    } else {
        if ( menu ) {
            WFreeMenu ( menu );
            menu = NULL;
        }
    }

    return( menu );
}

void *WInitDataFromMenu( WMenuEntry *entry, void *tdata )
{
    uint_16             *word;
    int                 tlen;
    char                *item_text;
    char                *text;

    while( entry ) {
        word = (uint_16 *)tdata;
        if( entry->item->IsPopup ) {
            *word = entry->item->Item.Popup.ItemFlags & ~MENU_ENDMENU;
            if( entry->next == NULL ) {
                *word |= MENU_ENDMENU;
            }
            text = tdata;
            text = text + sizeof( uint_16 );
            item_text = entry->item->Item.Popup.ItemText;
        } else {
            if( entry->item->Item.Normal.ItemFlags & MENU_SEPARATOR ) {
                *word = 0;
            } else {
                *word = entry->item->Item.Normal.ItemFlags & ~MENU_ENDMENU;
                *word |= MF_STRING;
            }
            if( entry->next == NULL ) {
                *word |= MENU_ENDMENU;
            }
            word++;
            if( entry->item->Item.Normal.ItemFlags & MENU_SEPARATOR ) {
                *word = 0;
            } else {
                *word = entry->item->Item.Normal.ItemID;
            }
            text = tdata;
            text = text + 2*sizeof( uint_16 );
            item_text = entry->item->Item.Normal.ItemText;
        }

        if( entry->is32bit ) {
            tlen = 0;
            if( item_text ) {
                if( WRmbcs2unicode( item_text, NULL, &tlen ) ) {
                    if( !WRmbcs2unicodeBuf( item_text, text, tlen ) ) {
                        tlen = 0;
                    }
                }
            }
            if( tlen == 0 ) {
                tlen = 2;
                text[0] = '\0';
                text[1] = '\0';
            }
        } else {
            if( item_text ) {
                tlen = strlen( item_text ) + 1;
                memcpy( text, item_text, tlen );
            } else {
                tlen = 1;
                text[0] = '\0';
            }
        }

        text += tlen;
        tdata = text;

        if( entry->item->IsPopup ) {
            if( entry->child != NULL ) {
                tdata = WInitDataFromMenu( entry->child, tdata );
            } else {
                WDummyMenuEntry->is32bit = entry->is32bit;
                tdata = WInitDataFromMenu( WDummyMenuEntry, tdata );
            }
        }
        entry = entry->next;
    }

    return( tdata );
}

int WCalcMenuSize( WMenuEntry *entry )
{
    int         size;
    int         tlen;
    char        *text;

    if( !entry ) {
        return( 0 );
    }

    size = 0;

    while( entry ) {
        if( entry->item->IsPopup ) {
            size += sizeof( MenuFlags ) + 1;
            text = entry->item->Item.Popup.ItemText;
            if( entry->child ) {
                size += WCalcMenuSize( entry->child );
            } else {
                WDummyMenuEntry->is32bit = entry->is32bit;
                size += WCalcMenuSize( WDummyMenuEntry );
            }
        } else {
            size += sizeof( MenuFlags ) + sizeof( uint_16 ) + 1;
            text = entry->item->Item.Normal.ItemText;
        }

        if( entry->is32bit ) {
            tlen = 0;
            if( text ) {
                if( !WRmbcs2unicode( text, NULL, &tlen ) ) {
                    tlen = 0;
                }
            }
            if( tlen == 0 ) {
                tlen = 2;
            }
        } else {
            if( text ) {
                tlen = strlen( text ) + 1;
            } else {
                tlen = 1;
            }
        }

        size += tlen;
        entry = entry->next;
    }

    return( size );
}

void WFreeMenu ( WMenu *menu )
{
    if ( menu ) {
        WFreeMenuEntries ( menu->first_entry );
        WMemFree ( menu );
    }
}

void WFreeMenuEntries ( WMenuEntry *entry )
{
    WMenuEntry *e;

    while ( entry ) {
        e = entry;
        entry = entry->next;
        if( e->child ) {
            WFreeMenuEntries ( e->child );
        }
        WFreeMenuEntry ( e );
    }
}

void WFreeMenuEntry ( WMenuEntry *entry )
{
    if( entry ) {
        if( entry->item ) {
            ResFreeMenuItem( entry->item );
        }
        if( entry->symbol ) {
            WMemFree( entry->symbol );
        }
        WMemFree( entry );
    }
}

Bool WRemoveMenuEntry ( WMenu *menu, WMenuEntry *entry )
{
    if( !menu || !entry ) {
        return( FALSE );
    }

    if( menu->first_entry == entry ) {
        menu->first_entry = entry->next;
    } else {
        if( entry->parent && (entry->parent->child == entry) ) {
            entry->parent->child = entry->next;
        }
    }
    if ( entry->next ) {
        entry->next->prev = entry->prev;
    }
    if ( entry->prev ) {
        entry->prev->next = entry->next;
    }

⌨️ 快捷键说明

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