punerea în aplicare a GTK MessageBox

voturi
28

Am încercat să pună în aplicare Win32 MessageBoxfolosind GTK. Aplicația utilizează SDL / OpenGL, astfel încât aceasta nu este o aplicație GTK.

Mă ocup de inițializarea ( gtk_init) un fel de lucruri în interiorul MessageBoxfuncției , după cum urmează:

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

Acum, eu sunt în nici un caz un programator cu experiență GTK, și îmi dau seama că eu sunt, probabil, fac ceva oribil greșit.

Cu toate acestea, problema mea este că ultimul dialog a apărut cu această funcție rămâne până în jurul valorii de ieșirile de proces. Vreo idee?

Întrebat 02/08/2008 la 00:27
sursa de către utilizator
În alte limbi...                            


3 răspunsuri

voturi
16

Hmmm, bine. Aș sugera un cod ca acest lucru, atunci:

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 este că aveți nevoie pentru a trece în jurul valorii de câteva bucăți de date. gtk_idle_add()Apelul adaugă o metodă pentru a fi rulat când bucla principală se execută și de mers în gol, iar FALSEvaloarea returnata de display_dialog()apel înseamnă că este rulat o singură dată. După ce vom obține rezultatul din dialogul, vom iesi din bucla principală. Asta va determina gtk_main()în principal MessageBox()metoda să se întoarcă, și vei putea accesa rezultatul de acolo.

Sper că acest lucru vă ajută!

Publicat 03/08/2008 la 03:30
sursa de către utilizator

voturi
6

Pentru a gestiona o casetă de dialog cu GTK +, utilizați un GtkDialog și gtk_dialog_run () în loc de a gestiona o buclă principală de tine fereastră și.

EDIT / ADDENDUM:

Ceea ce vreau să spun este „doar folosesc“: Nu înțeleg de ce vă creați un Windows pe care nu le utilizați niciodată și o buclă principală care pare inutil (cel puțin din bucata de cod ai postat). Poti scrie ceva la fel de scurt ca:

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;
    } 
}
Publicat 02/06/2010 la 16:59
sursa de către utilizator

voturi
5

Cateva lucruri:

Voi creați (și nu utilizați) o fereastră de toplevel inutile, numit window. Puteți șterge doar aceste linii:

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

De asemenea, fluxul nu pare destul de bine. gtk_main()începe bucla principală GTK, care blochează până când iese ceva. gtk_dialog_run()începe , de asemenea , o buclă principală, dar iese imediat ce unul dintre butoane este apasat.

Cred că ar putea fi de ajuns pentru tine pentru a elimina gtk_init_add()și de gtk_main()apeluri, și pur și simplu a face cu valoarea de returnare. De asemenea, gtk_widget_destroy()apelul nu este necesară, deoarece fereastra de dialog este distrusă automat când gtk_dialog_run) se întoarce (.

Publicat 02/08/2008 la 19:49
sursa de către utilizator

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