我一直在try 使用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程序员,我意识到我可能做了一些可怕的错误.

然而,我的问题是,最后一个对话框弹出时,这个函数会一直保留,直到进程退出.有什么 idea 吗?

推荐答案

嗯,好的.我建议这样的代码:

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
}

这个struct是必需的,因为你需要传递一些数据.gtk_idle_add()调用添加了一个在主循环运行且空闲时运行的方法,display_dialog()调用的FALSE返回值意味着它只运行一次.从对话框中得到结果后,我们退出主循环.这将导致主MessageBox()方法中的gtk_main()返回,并且您可以从那里访问结果.

Linux相关问答推荐

将参数#0更改为shell脚本不工作

C++17/Linux:信号未解锁单独线程中被阻止的网络套接字调用

如何正确Forking 并完成进程以避免 EAGAIN 错误

ShellScript,有更好的方法来查找具有特定名称和日期的文件吗?

Google Cloud Ops Agent Mongo 集成错误 - AuthenticationFailed:SCRAM 身份验证失败,storedKey 不匹配

Rust unix 进程

在 Windows 上通过 SSH 运行 django 应用程序

全屏(Fullscreen)小部件

如何在python中检索进程开始时间(或正常运行时间)

为什么在编译 K&R2 第 1 章中最长的行示例时出现getline 的类型冲突错误?

无法创建Java虚拟机

我如何从 Ubuntu 上的源代码自己构建 python?

size_t 和 off_t 的用法有什么区别?

分段故障处理

如何从命令行打开 Ubuntu Linux 上的 AVD 管理器?

用于数据库备份的 Linux shell 脚本

可以通过 SSH 连接的所有用户的列表

根据文件名模式和文件内容列出文件名?

是否有git sed或类似功能?

当我已经 ssh 进入远程机器时,如何 scp 回到本地?