GTK implementering av messagebox

stemmer
29

Jeg har prøvd å implementere Win32 er MessageBoxå bruke GTK. Applikasjonen bruke SDL / OpenGL, så dette er ikke et GTK app.

Jeg håndtere initialisering ( gtk_init) slags ting inni MessageBoxfunksjon som følger:

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

Nå er jeg på ingen måte en erfaren GTK programmerer, og jeg innser at jeg sannsynligvis gjør noe fryktelig galt.

Men mitt problem er at den siste dialogen dukket opp med denne funksjonen forblir rundt til prosess utganger. Noen ideer?

Publisert på 01/08/2008 klokken 23:27
kilden bruker
På andre språk...                            


3 svar

stemmer
16

Hmm ok. Jeg vil foreslå kode som dette, da:

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 er fordi du trenger å passere rundt et par stykker av data. Den gtk_idle_add()samtalen legger til en metode som skal kjøre når hovedsløyfen er i gang og inaktiv, og FALSEreturverdien fra display_dialog()samtalen betyr at det kun kjøres en gang. Etter at vi får resultatet fra dialogen, avslutter vi den viktigste loop. Det vil føre til at gtk_main()i MessageBox()hovedmetode for å gå tilbake, og du vil være i stand til å få tilgang til resultatet derfra.

Håper dette hjelper!

Svarte 03/08/2008 kl. 02:30
kilden bruker

stemmer
7

For å administrere en dialogboks med GTK +, bruk en GtkDialog og gtk_dialog_run () i stedet for å administrere et vindu og en hovedsløyfe selv.

EDIT / TILLEGG:

Det jeg mener er "bare bruke": Jeg forstår ikke hvorfor du oppretter en windows du aldri bruker og en hovedsløyfe som synes ubrukelig (minst fra den delen av koden du postet). Du kan skrive noe så kort som:

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;
    } 
}
Svarte 02/06/2010 kl. 15:59
kilden bruker

stemmer
6

Noen få ting:

Dere skaper (og ikke bruker) en unødvendig toppnivå vinduet, oppkalt window. Du kan bare slette disse linjene:

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

Også, strømmen ikke virker helt riktig. gtk_main()starter GTK viktigste loop, som blokkerer før noe kommer ut det. gtk_dialog_run()starter også en hoved loop, men det kommer ut så snart en av knappene er klikket.

Jeg tror det kan være nok for deg å fjerne gtk_init_add()og gtk_main()samtaler, og bare forholde seg til returverdien. Også gtk_widget_destroy()samtalen er unødvendig, da den dialogvindu automatisk ødelegges når gtk_dialog_run () returnerer.

Svarte 02/08/2008 kl. 18:49
kilden bruker

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