¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡{"
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡{"
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡{"
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡{"
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡{"
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡{"
};
/*¡¡calculate¡¡the¡¡number¡¡of¡¡menu_item's¡¡*/
static¡¡int¡¡nmenu_items¡¡=¡¡sizeof(menu_items)¡¡/¡¡sizeof(menu_items[0]);
static¡¡int¡¡initialize¡¡=¡¡TRUE;
static¡¡GtkMenuFactory¡¡*factory¡¡=¡¡NULL;
static¡¡GtkMenuFactory¡¡*subfactory[1];
static¡¡GHashTable¡¡*entry_ht¡¡=¡¡NULL;
void¡¡get_main_menu(GtkWidget¡¡**¡¡menubar,¡¡GtkAcceleratorTable¡¡**¡¡table)
{
¡¡¡¡¡¡¡¡if¡¡(initialize)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡menus_init();
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡if¡¡(menubar)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡*menubar¡¡=¡¡subfactory[0]->widget;
¡¡¡¡¡¡¡¡if¡¡(table)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡*table¡¡=¡¡subfactory[0]->table;
}
void¡¡menus_init(void)
{
¡¡¡¡¡¡¡¡if¡¡(initialize)¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡initialize¡¡=¡¡FALSE;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡factory¡¡=¡¡gtk_menu_factory_new(GTK_MENU_FACTORY_MENU_BAR);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡subfactory[0]¡¡=¡¡gtk_menu_factory_new(GTK_MENU_FACTORY_MENU_BAR);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡gtk_menu_factory_add_subfactory(factory,¡¡subfactory[0],¡¡"
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡menus_create(menu_items,¡¡nmenu_items);
¡¡¡¡¡¡¡¡}
}
void¡¡menus_create(GtkMenuEntry¡¡*¡¡entries,¡¡int¡¡nmenu_entries)
{
¡¡¡¡¡¡¡¡char¡¡*accelerator;
¡¡¡¡¡¡¡¡int¡¡i;
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡if¡¡(initialize)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡menus_init();
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡if¡¡(entry_ht)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡for¡¡(i¡¡=¡¡0;¡¡i¡¡<¡¡nmenu_entries;¡¡i++)¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡accelerator¡¡=¡¡g_hash_table_lookup(entry_ht,¡¡entries[i].path);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡if¡¡(accelerator)¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡if¡¡(accelerator[0]¡¡==¡¡'\0')
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡entries[i].accelerator¡¡=¡¡NULL;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡else
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡entries[i].accelerator¡¡=¡¡accelerator;
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡gtk_menu_factory_add_entries(factory,¡¡entries,¡¡nmenu_entries);
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡for¡¡(i¡¡=¡¡0;¡¡i¡¡<¡¡nmenu_entries;¡¡i++)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡if¡¡(entries[i].widget)¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡gtk_signal_connect(GTK_OBJECT(entries[i].widget),¡¡"install_accelerator",
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡(GtkSignalFunc)¡¡menus_install_accel,
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡entries[i].path);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡gtk_signal_connect(GTK_OBJECT(entries[i].widget),¡¡"remove_accelerator",
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡(GtkSignalFunc)¡¡menus_remove_accel,
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡entries[i].path);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡}
}
static¡¡gint¡¡menus_install_accel(GtkWidget¡¡*¡¡widget,¡¡gchar¡¡*¡¡signal_name,¡¡gchar¡¡key,¡¡gchar¡¡modifiers,¡¡gchar¡¡*¡¡path)
{
¡¡¡¡¡¡¡¡char¡¡accel[64];
¡¡¡¡¡¡¡¡char¡¡*t1,¡¡t2[2];
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡accel[0]¡¡=¡¡'\0';
¡¡¡¡¡¡¡¡if¡¡(modifiers¡¡&¡¡GDK_CONTROL_MASK)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡strcat(accel,¡¡"
¡¡¡¡¡¡¡¡if¡¡(modifiers¡¡&¡¡GDK_SHIFT_MASK)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡strcat(accel,¡¡"
¡¡¡¡¡¡¡¡if¡¡(modifiers¡¡&¡¡GDK_MOD1_MASK)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡strcat(accel,¡¡"
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡t2[0]¡¡=¡¡key;
¡¡¡¡¡¡¡¡t2[1]¡¡=¡¡'\0';
¡¡¡¡¡¡¡¡strcat(accel,¡¡t2);
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡if¡¡(entry_ht)¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡t1¡¡=¡¡g_hash_table_lookup(entry_ht,¡¡path);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡g_free(t1);
¡¡¡¡¡¡¡¡}¡¡else
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡entry_ht¡¡=¡¡g_hash_table_new(g_string_hash,¡¡g_string_equal);
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡g_hash_table_insert(entry_ht,¡¡path,¡¡g_strdup(accel));
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡return¡¡TRUE;
}
static¡¡void¡¡menus_remove_accel(GtkWidget¡¡*¡¡widget,¡¡gchar¡¡*¡¡signal_name,¡¡gchar¡¡*¡¡path)
{
¡¡¡¡¡¡¡¡char¡¡*t;
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡if¡¡(entry_ht)¡¡{
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡t¡¡=¡¡g_hash_table_lookup(entry_ht,¡¡path);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡g_free(t);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡g_hash_table_insert(entry_ht,¡¡path,¡¡g_strdup(""));
¡¡¡¡¡¡¡¡}
}
void¡¡menus_set_sensitive(char¡¡*path,¡¡int¡¡sensitive)
{
¡¡¡¡¡¡¡¡GtkMenuPath¡¡*menu_path;
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡if¡¡(initialize)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡menus_init();
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡menu_path¡¡=¡¡gtk_menu_factory_find(factory,¡¡path);
¡¡¡¡¡¡¡¡if¡¡(menu_path)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡gtk_widget_set_sensitive(menu_path->widget,¡¡sensitive);
¡¡¡¡¡¡¡¡else
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡g_warning("Unable¡¡to¡¡set¡¡sensitivity¡¡for¡¡menu¡¡which¡¡doesn't¡¡exist:¡¡%s",¡¡path);
}
And¡¡here's¡¡the¡¡main.h¡¡
#ifndef¡¡__MAIN_H__
#define¡¡__MAIN_H__
#ifdef¡¡__cplusplus
extern¡¡"C"¡¡{
#endif¡¡/*¡¡__cplusplus¡¡*/
void¡¡file_quit_cmd_callback(GtkWidget¡¡*widget,¡¡gpointer¡¡data);
#ifdef¡¡__cplusplus
}
#endif¡¡/*¡¡__cplusplus¡¡*/
#endif¡¡/*¡¡__MAIN_H__¡¡*/
And¡¡main.c¡¡
#include¡¡
#include¡¡"main.h"
#include¡¡"menus.h"
int¡¡main(int¡¡argc,¡¡char¡¡*argv[])
{
¡¡¡¡¡¡¡¡GtkWidget¡¡*window;
¡¡¡¡¡¡¡¡GtkWidget¡¡*main_vbox;
¡¡¡¡¡¡¡¡GtkWidget¡¡*menubar;
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡GtkAcceleratorTable¡¡*accel;
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡gtk_init(&argc,¡¡&argv);
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡window¡¡=¡¡gtk_window_new(GTK_WINDOW_TOPLEVEL);
¡¡¡¡¡¡¡¡gtk_signal_connect(GTK_OBJECT(window),¡¡"destroy",¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡GTK_SIGNAL_FUNC(file_quit_cmd_callback),¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡"WM¡¡destroy");
¡¡¡¡¡¡¡¡gtk_window_set_title(GTK_WINDOW(window),¡¡"Menu¡¡Factory");
¡¡¡¡¡¡¡¡gtk_widget_set_usize(GTK_WIDGET(window),¡¡300,¡¡200);
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡main_vbox¡¡=¡¡gtk_vbox_new(FALSE,¡¡1);
¡¡¡¡¡¡¡¡gtk_container_border_width(GTK_CONTAINER(main_vbox),¡¡1);
¡¡¡¡¡¡¡¡gtk_container_add(GTK_CONTAINER(window),¡¡main_vbox);
¡¡¡¡¡¡¡¡gtk_widget_show(main_vbox);
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡get_main_menu(&menubar,¡¡&accel);
¡¡¡¡¡¡¡¡gtk_window_add_accelerator_table(GTK_WINDOW(window),¡¡accel);
¡¡¡¡¡¡¡¡gtk_box_pack_start(GTK_BOX(main_vbox),¡¡menubar,¡¡FALSE,¡¡TRUE,¡¡0);
¡¡¡¡¡¡¡¡gtk_widget_show(menubar);
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡gtk_widget_show(window);
¡¡¡¡¡¡¡¡gtk_main();
¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡return(0);
}
/*¡¡This¡¡is¡¡just¡¡to¡¡demonstrate¡¡how¡¡callbacks¡¡work¡¡when¡¡using¡¡the
¡¡*¡¡menufactory.¡¡¡¡Often,¡¡people¡¡put¡¡all¡¡the¡¡callbacks¡¡from¡¡the¡¡menus
¡¡*¡¡in¡¡a¡¡separate¡¡file,¡¡and¡¡then¡¡have¡¡them¡¡call¡¡the¡¡appropriate¡¡functions
¡¡*¡¡from¡¡there.¡¡¡¡Keeps¡¡it¡¡more¡¡organized.¡¡*/
void¡¡file_quit_cmd_callback¡¡(GtkWidget¡¡*widget,¡¡gpointer¡¡data)
{
¡¡¡¡¡¡¡¡g_print¡¡("%s\n",¡¡(char¡¡*)¡¡data);
¡¡¡¡¡¡¡¡gtk_exit(0);
}
ÕâÀïÊÇmakefile.¡¡
CC¡¡¡¡¡¡¡¡¡¡¡¡=¡¡gcc
PROF¡¡¡¡¡¡¡¡=¡¡-g
C_FLAGS¡¡=¡¡¡¡-Wall¡¡$(PROF)¡¡-L/usr/local/include¡¡-DDEBUG
L_FLAGS¡¡=¡¡¡¡$(PROF)¡¡-L/usr/X11R6/lib¡¡-L/usr/local/lib¡¡
L_POSTFLAGS¡¡=¡¡-lgtk¡¡-lgdk¡¡-lglib¡¡-lXext¡¡-lX11¡¡-lm
PROGNAME¡¡=¡¡at
O_FILES¡¡=¡¡menus.o¡¡main.o
$(PROGNAME):¡¡$(O_FILES)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rm¡¡-f¡¡$(PROGNAME)
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡$(CC)¡¡$(L_FLAGS)¡¡-o¡¡$(PROGNAME)¡¡$(O_FILES)¡¡$(L_POSTFLAGS)
.c.o:¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡$(CC)¡¡-c¡¡$(C_FLAGS)¡¡$<
clean:¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rm¡¡-f¡¡core¡¡*.o¡¡$(PROGNAME)¡¡nohup.out
distclean:¡¡clean¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rm¡¡-f¡¡*~
--------------------------------------------------------------------------------
¡¡¡¡¡¡ (http://www.fanqiang.com)
![[ ÓÀÔ¶µÄUNIX::UNIX¼¼Êõ×ÊÁϵı¦¿â ]](/images/title.gif)