📄 w_menu.c
字号:
/****************************************************************************
*
* 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 + -