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 + -
显示快捷键?