Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C MessageBox的GTK实现_C_Linux_Gtk_X11 - Fatal编程技术网

C MessageBox的GTK实现

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_

我一直在尝试使用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_init(&gtkArgc, &gtkArgv);
    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
返回值意味着它只运行一次。从对话框中得到结果后,我们退出主循环。这将导致main
MessageBox()
方法中的
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;
    } 
}