C MessageBox的GTK实现
我一直在尝试使用GTK实现Win32的C MessageBox的GTK实现,c,linux,gtk,x11,C,Linux,Gtk,X11,我一直在尝试使用GTK实现Win32的MessageBox。该应用程序使用SDL/OpenGL,因此这不是GTK应用程序 我在MessageBox函数中处理初始化(gtk_init)之类的东西,如下所示: int MessageBox(HWND hwnd, const char* text, const char* caption, UINT type) { GtkWidget *window = NULL; GtkWidget *dialog = NULL; gtk_
MessageBox
。该应用程序使用SDL/OpenGL,因此这不是GTK应用程序
我在MessageBox
函数中处理初始化(gtk_init
)之类的东西,如下所示:
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程序员,我意识到我可能做了一些可怕的错误
但是,我的问题是,最后一个对话框弹出时,该函数一直保留到进程退出。有什么想法吗?有几点:
您正在创建(而不是使用)一个不必要的顶级窗口,名为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\u widget\u destroy()
调用是不必要的,因为当gtk\u dialog\u run()返回时,对话框窗口会自动被销毁。Hmm,ok。我建议这样的代码,然后:
typedef结构{
int型;
int结果;
}对话数据;
静态gboolean
显示\u对话框(gpointer用户\u数据)
{
DialogData*dialog_data=用户_数据;
GtkWidget*对话框;
如果(对话框\u data->type&MB\u YESNO)
dialog=gtk_message_dialog_new(…);
其他的
dialog=gtk_message_dialog_new(…);
//设置标题等。
dialog_data->result=gtk_dialog_run(…);
gtk_main_quit();//退出MessageBox()中的主循环运行
返回FALSE;
}
int MessageBox(…)
{
对话数据对话数据;
dialog_data.type=类型;
gtk_idle_add(显示对话框和对话框数据);
gtk_main();
//根据dialog_data.result执行操作
}
结构是必需的,因为您需要传递几段数据。
gtk_idle_add()
调用添加了一个在主循环运行且空闲时要运行的方法,而display_dialog()
调用的FALSE
返回值意味着它只运行一次。从对话框中得到结果后,我们退出主循环。这将导致mainMessageBox()
方法中的gtk_main()
返回,您将能够从那里访问结果。要使用gtk+管理对话框,请使用GtkDialog,而不是自己管理窗口和主循环
编辑/补遗:
我的意思是“只是使用”:我不明白为什么你要创建一个从未使用过的窗口和一个看起来毫无用处的主循环(至少从你发布的代码来看)。你可以写一些简短的东西,比如:
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;
}
}