GTK Implementierung von MessageBox

stimmen
28

Ich habe versucht , Win32 zu implementieren ist MessageBoxmit GTK. Die App SDL / OpenGL verwenden, so ist dies kein GTK App.

Ich kümmere mich um die Initialisierung ( gtk_init) Art des Materials in der MessageBoxFunktion wie folgt:

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

Nun, ich bin keineswegs ein erfahrener GTK Programmierer, und ich weiß, dass ich wahrscheinlich etwas schrecklich falsch tue.

Allerdings ist mein Problem, dass der letzte Dialog tauchte mit dieser Funktion, bis der Prozess beendet bleibt herum. Irgendwelche Ideen?

Veröffentlicht am 02/08/2008 um 00:27
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
16

Hmm, ok. Ich würde der Code wie folgt vorschlagen, dann gilt:

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
}

Die Struktur ist so, weil Sie ein paar Stücke von Daten zu übergeben um benötigen. Der gtk_idle_add()Aufruf fügt eine Methode ausgeführt wird , wenn die Hauptschleife ausgeführt wird und im Leerlauf, und der FALSERückgabewert des display_dialog()Anruf bedeutet , dass es nur einmal Lauf. Nachdem wir das Ergebnis aus dem Dialog erhalten, verlassen wir die Hauptschleife. Das wird die Ursache gtk_main()in der HauptmethodeMessageBox() zurückzukehren, und Sie werden in der Lage , das Ergebnis für den Zugriff auf von dort.

Hoffe das hilft!

Beantwortet am 03/08/2008 um 03:30
quelle vom benutzer

stimmen
6

Um ein Dialogfeld mit GTK + zu verwalten, verwenden Sie ein GtkDialog und gtk_dialog_run () stattdessen ein Fenster mit der Verwaltung und eine Hauptschleife selbst.

EDIT / NACHTRAG:

Was ich meine ist „nur verwenden“: Ich verstehe nicht, warum Sie ein Fenster erstellen Sie nie eine Hauptschleife verwenden und die (zumindest aus dem Stück Code, den Sie geschrieben) nutzlos scheint. Sie können etwas so kurz wie schreiben:

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;
    } 
}
Beantwortet am 02/06/2010 um 16:59
quelle vom benutzer

stimmen
5

Ein paar Dinge:

Sie erstellen (und nicht verwendet wird ) ein unnötiges Toplevel - Fenster, genannt window. Sie können nur diese Zeilen löschen:

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

Auch dann , wenn die Strömung nicht ganz richtig zu sein scheint. gtk_main()startet die Hauptschleife GTK, die blockiert , bis etwas , das es austritt. gtk_dialog_run()startet auch eine Hauptschleife, aber es beendet, sobald eine der Schaltflächen geklickt wird.

Ich denke , es könnte genug für Sie , die entfernen gtk_init_add()und gtk_main()Anrufe und einfach mit dem Rückgabewert befassen. Auch der gtk_widget_destroy()Ruf ist nicht erforderlich, da das Dialogfenster automatisch zerstört wird , wenn gtk_dialog_run () zurückkehrt.

Beantwortet am 02/08/2008 um 19:49
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more