GTK实现的MessageBox
的我一直在努力实现的Win32的使用MessageBox
GTK。该应用程序使用SDL/OpenGL,所以这不是一个GTK应用程序。GTK实现的MessageBox
我处理初始化(gtk_init
)之类的东西MessageBox
函数内部如下:
int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
GtkWidget *window = NULL;
GtkWidget *dialog = NULL;
gtk_init(>kArgc, >kArgv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
// gcallback calls gtk_main_quit()
gtk_init_add((GtkFunction)gcallback, NULL);
if (type & MB_YESNO) {
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text);
} else {
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text);
}
gtk_window_set_title(GTK_WINDOW(dialog), caption);
gint result = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_main();
gtk_widget_destroy(dialog);
if (type & MB_YESNO) {
switch (result) {
default:
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_NO:
return IDNO;
break;
case GTK_RESPONSE_YES:
return IDYES;
break;
}
}
return IDOK;
}
现在,我决不是一个有经验的程序员GTK,我意识到,我可能做的事情可怕的错误。
不过,我的问题是,最后一个对话框弹出使用此功能总是在那里,直到进程退出。有任何想法吗?
嗯,好的。我建议这样的代码,然后:
typedef struct {
int type;
int result;
} DialogData;
static gboolean
display_dialog(gpointer user_data)
{
DialogData *dialog_data = user_data;
GtkWidget *dialog;
if (dialog_data->type & MB_YESNO)
dialog = gtk_message_dialog_new(...);
else
dialog = gtk_message_dialog_new(...);
// Set title, etc.
dialog_data->result = gtk_dialog_run(...);
gtk_main_quit(); // Quits the main loop run in MessageBox()
return FALSE;
}
int MessageBox(...)
{
DialogData dialog_data;
dialog_data.type = type;
gtk_idle_add(display_dialog, &dialog_data);
gtk_main();
// Do stuff based on dialog_data.result
}
该结构是因为你需要传递几个数据片段。该gtk_idle_add()
调用增加了一个方法,主回路运行时要运行和闲置,并从display_dialog()
调用FALSE
返回值意味着它只能运行一次。从对话框中得到结果后,我们退出主循环。这会导致MessageBox()
方法中的gtk_main()
返回,并且您将能够从那里访问结果。
希望这会有所帮助!
有几件事情:
你正在创建(而不是使用)不必要的顶层窗口,命名为window
。您可以删除这些行:
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
此外,流程似乎不太正确。 gtk_main()
启动GTK主循环,该循环阻塞直到出现它。 gtk_dialog_run()
也会启动一个主循环,但只要其中一个按钮被点击就会退出。
我认为这可能足以让您删除gtk_init_add()
和gtk_main()
调用,并简单地处理返回值。另外调用gtk_widget_destroy()
也是不必要的,因为当gtk_dialog_run()返回时,对话窗口会自动销毁。
要使用GTK +管理对话框,请使用GtkDialog和gtk_dialog_run(),而不是自行管理窗口和主循环。
编辑/附录:
我的意思是“只使用”:我不明白为什么要创建一个Windows从不使用和好像没用(至少从片的主循环你发布的代码)。你可以写短的东西:
int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type)
{
GtkWidget *dialog ;
/* Instead of 0, use GTK_DIALOG_MODAL to get a modal dialog box */
if (type & MB_YESNO)
dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, text);
else
dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, text);
gtk_window_set_title(GTK_WINDOW(dialog), caption);
gint result = gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(GTK_WIDGET(dialog));
if (type & MB_YESNO)
{
switch (result)
{
default:
case GTK_RESPONSE_DELETE_EVENT:
case GTK_RESPONSE_NO:
return IDNO;
case GTK_RESPONSE_YES:
return IDYES;
}
return IDOK;
}
}