c - tutorial - messagebox example

GTK implementation of MessageBox (4)

I have been trying to implement Win32's MessageBox using GTK. The app using SDL/OpenGL, so this isn't a GTK app.

I handle the initialisation (gtk_init) sort of stuff inside the MessageBox function as follows:

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



    if (type & MB_YESNO) {
        switch (result) {
        case GTK_RESPONSE_NO:
            return IDNO;
        case GTK_RESPONSE_YES:
            return IDYES;

    return IDOK;

Now, I am by no means an experienced GTK programmer, and I realise that I'm probably doing something horribly wrong.

However, my problem is that the last dialog popped up with this function stays around until the process exits. Any ideas?

A few things:

You are creating (and not using) an unnecessary toplevel window, named window. You can just 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 flow doesn't seem quite right. gtk_main() starts the GTK main loop, which blocks until something exits it. gtk_dialog_run() also starts a main loop, but it exits as soon as one of the buttons is clicked.

I think it might be enough for you to remove the gtk_init_add() and gtk_main() calls, and simply deal with the return value. Also the gtk_widget_destroy() call is unnecessary, as the dialog window is automatically destroyed when gtk_dialog_run() returns.

Hmm, ok. I'd suggest code like this, then:

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


    // Do stuff based on dialog_data.result

The struct is because you need to pass around a couple pieces of data. The gtk_idle_add() call adds a method to be run when the main loop is running and idle, and the FALSE return value from the display_dialog() call means that it's only run once. After we get the result from the dialog, we quit the main loop. That'll cause the gtk_main() in your main MessageBox() method to return, and you'll be able to access the result from there.

Hope this helps!

Qt implementation of MessageBox

You are tring to show a message box from a console application right ?

If this is correct you need to add this line in your pro file:

QT += gui

After you have done that in your main.cpp file write something like this. Qt creates an event loop for you

#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QMessageBox>
#include <QApplication>

int main(int argc, char *argv[])
    QApplication a(argc, argv);


    return a.exec();

SFML and GTK+ - GtkFileChooserDialog

In the gtk_dialog_run documentation there is a note

After gtk_dialog_run() returns, you are responsible for hiding or destroying the dialog if you wish to do so.

So the dialog should not get destroyed automaticaly, the programmer must do it.


The another problem is that you are not running GTK main loop (gtk_main() or its variant) so the GTK can not deal with events necessary to destroy a widget (no part of GTK is running in the time the events are present). The sollution for this is in answer to another question using gtk_idle_add() to invoke function after gtk_main() is called. In this function the dialog is shown, the result is given to the caller, the dialog is destroyed and gtk_main_quit() is called to terminate GTK main loop.

However, gtk_idle_add() is deprecated in GTK+2.6 and is not present in GTK+3.0, so g_idle_add() should be used instead. Your code could be somethink like

struct fch_result {
    gint response;
    // other information to return like filename,...

static gboolean fch_dialog(gpointer user_data)
    struct fch_result *result = (struct fch_result *) user_data;
    GtkWidget *dialog = gtk_file_chooser_dialog_new ( ... );
    result->response = gtk_dialog_run (GTK_DIALOG(dialog));
    // now add other information to result

    gtk_main_quit();  // terminate the gtk_main loop called from caller
    return FALSE;

int main(int argc, char** argv)
    gtk_init(&argc, &argv);

    struct fch_result data;
    g_idle_add(fch_dialog, &data);


    // continue with the program
    return 0;