Frage

Ich habe versucht, Win32 zu implementieren MessageBox mit GTK.Die App verwendet SDL/OpenGL, es handelt sich also nicht um eine GTK-App.

Ich kümmere mich um die Initialisierung (gtk_init) Art Zeug im Inneren MessageBox Funktion 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 bin ich kein erfahrener GTK-Programmierer und mir ist klar, dass ich wahrscheinlich etwas furchtbar falsch mache.

Mein Problem ist jedoch, dass der letzte Dialog, der mit dieser Funktion angezeigt wurde, bestehen bleibt, bis der Prozess beendet wird.Irgendwelche Ideen?

War es hilfreich?

Lösung

Hm, ok.Ich würde dann Code wie diesen vorschlagen:

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 liegt daran, dass Sie einige Daten weitergeben müssen.Der gtk_idle_add() call fügt eine Methode hinzu, die ausgeführt werden soll, wenn die Hauptschleife läuft und inaktiv ist, und die FALSE Rückgabewert von der display_dialog() Aufruf bedeutet, dass es nur einmal ausgeführt wird.Nachdem wir das Ergebnis des Dialogs erhalten haben, verlassen wir die Hauptschleife.Das wird dazu führen gtk_main() in deiner Hauptsache MessageBox() Methode zurückzugeben, und Sie können von dort aus auf das Ergebnis zugreifen.

Hoffe das hilft!

Andere Tipps

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

BEARBEITUNG / NACHTRAG:

Was ich meine ist „einfach verwenden“:Ich verstehe nicht, warum Sie ein Fenster erstellen, das Sie nie verwenden, und eine Hauptschleife, die nutzlos erscheint (zumindest aus dem Code, den Sie gepostet haben).Sie können etwas so Kurzes schreiben wie:

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

Ein paar Dinge:

Sie erstellen (und verwenden nicht) ein unnötiges Fenster der obersten Ebene mit dem Namen window.Sie können einfach 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);

Außerdem scheint der Fluss nicht ganz richtig zu sein. gtk_main() startet die GTK-Hauptschleife, die blockiert, bis etwas sie verlässt. gtk_dialog_run() startet auch eine Hauptschleife, die jedoch beendet wird, sobald auf eine der Schaltflächen geklickt wird.

Ich denke, es könnte ausreichen, wenn Sie das entfernen gtk_init_add() Und gtk_main() Aufrufe und kümmern sich einfach um den Rückgabewert.Auch der gtk_widget_destroy() Der Aufruf ist unnötig, da das Dialogfenster automatisch zerstört wird, wenn gtk_dialog_run() zurückkehrt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top