Pregunta

He estado tratando de implementar Win32 s MessageBox el uso de GTK.La aplicación usando SDL/OpenGL, así que esto no es una aplicación GTK.

Puedo manejar la inicialización (gtk_init) tipo de cosas dentro de la MessageBox una función como la siguiente:

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

Ahora, yo soy de ninguna manera un experimentado GTK programador, y me doy cuenta de que probablemente estoy haciendo algo terriblemente mal.

Sin embargo, mi problema es que el último diálogo que apareció con esta función se mantiene alrededor hasta que el proceso termina.Alguna idea?

¿Fue útil?

Solución

Hmm, ok.Me gustaría sugerir un código como este, entonces:

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
}

La estructura es debido a que usted necesita para pasar alrededor de un par de piezas de datos.El gtk_idle_add() llame añade un método que se ejecuta cuando el bucle principal se está ejecutando y de reposo, y el FALSE valor de retorno de la display_dialog() llame significa que sólo se ejecute una vez.Después de obtener el resultado en el cuadro de diálogo, se salga del bucle principal.Que va a causar la gtk_main() en su principal MessageBox() método para devolver, y usted será capaz de acceder al resultado a partir de ahí.

Espero que esto ayude!

Otros consejos

Para administrar un cuadro de diálogo con GTK+, el uso de un GtkDialog y gtk_dialog_run() en lugar de administrar una ventana y un bucle principal por ti mismo.

EDITAR / ANEXO :

Lo que quiero decir es "uso" :No entiendo por qué crear un windows que nunca uso y un bucle principal que parece inútil (al menos desde el trozo de código que has publicado).Usted puede escribir algo tan corto como :

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

Un par de cosas:

Usted está creando (y no uso) de un innecesario de la ventana principal, llamado window.Sólo se puede eliminar estas líneas:

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

También, el flujo, no parece muy correcto. gtk_main() comienza el GTK bucle principal, que bloquea hasta que algo sale de ella. gtk_dialog_run() también se inicia un bucle principal, pero sale tan pronto como uno de los botones que se hace clic.

Yo creo que puede ser suficiente para eliminar el gtk_init_add() y gtk_main() las llamadas, y se limita a tratar con el valor de retorno.También la gtk_widget_destroy() la llamada es innecesario, ya que la ventana de diálogo se destruye automáticamente cuando gtk_dialog_run() devuelve.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top