GTK execution of MessageBox

I have actually been attempting to implement Win32's MessageBox making use of GTK. The application making use of SDL/OpenGL, so this isn't a GTK application.

I take care of the initialisation (gtk_init) type of things inside the MessageBox function as adheres to:

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;
} 

Currently, I am by no suggests a seasoned GTK designer, and also I become aware that I'm possibly doing something badly incorrect.

Nonetheless, my trouble is that the last dialog turned up with this function remains about till the procedure leaves. Any kind of suggestions?

0
2019-05-03 23:09:08
Source Share
Answers: 2

A couple of points:

You are developing (and also not making use of) an unneeded toplevel window, called window. You can simply delete these lines:

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);

Also, the circulation does not appear fairly appropriate. gtk_main() begins the GTK major loop, which obstructs till something leaves it. gtk_dialog_run() additionally begins a major loop, yet it leaves as quickly as among the switches is clicked.

I assume it could be sufficient for you to remove the gtk_init_add() and also gtk_main() telephone calls, and also merely manage the return value. Additionally the gtk_widget_destroy() call is unneeded, as the dialog window is instantly damaged when gtk_dialog_run () returns.

0
2019-05-09 08:32:37
Source

Hmm, ok. I would certainly recommend code similar to this, after that :

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
}

The struct is due to the fact that you require to circulate a pair items of information. The gtk_idle_add() call includes a method to be run when the major loop is running and also still, and also the FALSE return value from the display_dialog() call suggests that it's just run as soon as. After we get the arise from the dialog, we gave up the major loop. That'll create the gtk_main() in your major MessageBox() method to return, and also you'll have the ability to access the arise from there.

Hope this aids!

0
2019-05-08 15:04:15
Source