εφαρμογή GTK της MessageBox

ψήφοι
28

Έχω προσπαθήσει να εφαρμόσει Win32 για MessageBoxχρήση GTK. Η εφαρμογή με τη χρήση της SDL / OpenGL, έτσι αυτό δεν είναι μια εφαρμογή GTK.

Έχω χειριστεί την αρχικοποίηση ( gtk_initείδος) τα πράγματα στο εσωτερικό του MessageBoxλειτουργία ως εξής:

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, και συνειδητοποιώ ότι είμαι κατά πάσα πιθανότητα να κάνει κάτι τρομερά λάθος.

Ωστόσο, το πρόβλημά μου είναι ότι η τελευταία διαλόγου έσκασε με τη λειτουργία αυτή παραμένει περίπου μέχρι τις εξόδους της διαδικασίας. Καμιά ιδέα?

Δημοσιεύθηκε 02/08/2008 στις 00:27
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
16

Χμμ, εντάξει. Θα πρότεινα τον κωδικό όπως αυτό, τότε:

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()κλήση προσθέτει μια μέθοδο που θα τρέξει, όταν ο κύριος βρόχος εκτελείται και σε αδράνεια, και η FALSEτιμή επιστροφής από την display_dialog()κλήση σημαίνει ότι έχει εκτελεστεί μόνο μία φορά. Μετά παίρνουμε το αποτέλεσμα από το παράθυρο διαλόγου, θα εγκαταλείψει τον κύριο βρόγχο. Αυτό θα προκαλέσει το gtk_main()στην κύρια σας MessageBox()μέθοδο για να επιστρέψει, και θα είστε σε θέση να έχουν πρόσβαση στο αποτέλεσμα από εκεί.

Η ελπίδα αυτό βοηθά!

Απαντήθηκε 03/08/2008 στις 03:30
πηγή χρήστη

ψήφοι
6

Για να διαχειριστείτε ένα παράθυρο διαλόγου με GTK +, χρησιμοποιήστε ένα GtkDialog και gtk_dialog_run () αντί της διαχείρισης ενός παραθύρου και ένα κύριο βρόγχο από τον εαυτό σας.

EDIT / ΠΡΟΣΘΗΚΗ:

Αυτό που εννοώ είναι «απλά χρησιμοποιήστε»: Δεν καταλαβαίνω γιατί να δημιουργήσετε ένα παράθυρα που δεν χρησιμοποιούν ποτέ και ένα κύριο βρόγχο που φαίνεται άχρηστο (τουλάχιστον από το κομμάτι του κώδικα που δημοσιεύτηκε). Μπορείτε να γράψετε κάτι όσο το:

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;
    } 
}
Απαντήθηκε 02/06/2010 στις 16:59
πηγή χρήστη

ψήφοι
5

Λίγα πράγματα:

Δημιουργείτε (και όχι με τη χρήση) περιττό ανωτέρου επιπέδου παράθυρο, που ονομάζεται window. Μπορείτε να διαγράψετε μόνο αυτές τις γραμμές:

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

Επίσης, η ροή δεν φαίνεται αρκετά σωστό. gtk_main()ξεκινά το κύριο βρόχο GTK, η οποία μπλοκάρει μέχρι κάτι βγαίνει. gtk_dialog_run()ξεκινά επίσης ένα κύριο βρόχο, αλλά βγαίνει μόλις ένα από τα πλήκτρα έχει πατηθεί.

Νομίζω ότι μπορεί να είναι αρκετό για να μπορείτε να αφαιρέσετε τα gtk_init_add()και gtk_main()κλήσεις, και απλά ασχολούνται με την τιμή επιστροφής. Επίσης, η gtk_widget_destroy()κλήση δεν είναι απαραίτητη, καθώς το παράθυρο διαλόγου αυτόματα καταστρέφεται όταν gtk_dialog_run () επιστρέφει.

Απαντήθηκε 02/08/2008 στις 19:49
πηγή χρήστη

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